# ..title    > An Introduction to Programming in Emacs Lisp
..title      > Una introducción a la programación en Emacs Lisp
# ..subtitle > Revised Third Edition
..subtitle   > Revisada la tercera edición
# ..author   > Robert J. Chassell
..author     > Robert J. Chassell
..translator > David Arroyo Menéndez
..translator > nasciiboy
# ..lang     > en
..lang       > es
# ..style    > worg-data/worg.css
..style      > worg-data/worg.css
# ..id       > ISBN 1-882114-43-4
# ..options  > fancyCode toc
..options    > fancyCode toc

# @ 2-en-morg: [keep-lines "^$\|^#" ] && [replace-regexp "^# ?" ""]
# $ awk 'length == 0 || /^#/' emacs-lisp-intro_es.porg | sed -e 's/^# \?//' | sed '8,11d' > emacs-lisp-intro.morg
# @ 2-es-morg: [morg unPorg txt.porg] || [flush-lines "^#"]

# This is an @e(Introduction to Programming in Emacs Lisp), for people who are
# not programmers.
Esto es una @e{Introducción a la Programación en Emacs Lisp}, para personas que
no son programadoras.

# Edition 3.10, 28 October 2009
Traducido desde la edición 3.10

# Copyright ® 1990–1995, 1997, 2001–2013 Free Software Foundation, Inc.
Copyright ® 1990–1995, 1997, 2001–2013 Free Software Foundation, Inc.

# Published by the:
#
# ..pret >
#   GNU Press,                        http://www.fsf.org/campaigns/gnu-press/
#   a division of the                                    email: sales@@fsf.org
#   Free Software Foundation, Inc.                     Tel: +1 (617) 542-5942
#   51 Franklin Street, Fifth Floor                    Fax: +1 (617) 542-2652
#   Boston, MA 02110-1301 USA
# < pret..
#
# ISBN 1-882114-43-4
#
# Permission is granted to copy, distribute and/or modify this document under the
# terms of the GNU Free Documentation License, Version 1.3 or any later version
# published by the Free Software Foundation; there being no Invariant Section, with
# the Front-Cover Texts being “A GNU Manual”, and with the Back-Cover Texts as
# in (a) below. A copy of the license is included in the section entitled “GNU Free
# Documentation License”.
Permission is granted to copy, distribute and/or modify this document under
the terms of the GNU Free Documentation License, Version 1.3 or any later
version published by the Free Software Foundation; there being no Invariant
Section, with the Front-Cover Texts being “A GNU Manual”, and with the
Back-Cover Texts as in (a) below. A copy of the license is included in the
section entitled “GNU Free Documentation License”.

# (a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify this
# GNU manual. Buying copies from the FSF supports it in developing GNU and
# promoting software freedom.”
(a) The FSF's Back-Cover Text is: “You have the freedom to copy and modify
this GNU manual. Buying copies from the FSF supports it in developing GNU
and promoting software freedom.”

# * Preface
* Prefacio

#   Most of the GNU Emacs integrated environment is written in the programming
#   language called Emacs Lisp. The code written in this programming language
#   is the software––the sets of instructions––that tell the computer what to
#   do when you give it commands. Emacs is designed so that you can write new
#   code in Emacs Lisp and easily install it as an extension to the editor.
  La mayoría del entorno integrado GNU Emacs está escrito en el lenguaje de
  programación llamado Emacs Lisp. El código escrito en este lenguaje de
  programación es el software––el conjunto de instrucciones––que le indican al
  ordenador qué hacer cuando se le dan comandos. Emacs está diseñado de forma
  que se pueda escribir nuevo código en Emacs Lisp e instalarlo fácilmente como
  una extensión al editor.

#   (GNU Emacs is sometimes called an “extensible editor”, but it does much
#   more than provide editing capabilities. It is better to refer to Emacs as
#   an “extensible computing environment”. However, that phrase is quite a
#   mouthful. It is easier to refer to Emacs simply as an editor. Moreover,
#   everything you do in Emacs––find the Mayan date and phases of the moon,
#   simplify polynomials, debug code, manage files, read letters, write
#   books––all these activities are kinds of editing in the most general sense
#   of the word.)
  (GNU Emacs se define muchas veces como un “editor extensible”, pero hace
  mucho más que proporcionar capacidad de edición. Es mejor referirse a Emacs
  como un “entorno de computación extensible”. Sin embargo, esa frase es un
  poco pretenciosa. Es más fácil referirse a Emacs simplemente como un
  editor. De hecho, cada cosa que se hace en Emacs––encontrar la fecha Maya y
  fases de la luna, simplificar polinomios, depurar código, administrar
  ficheros, leer cartas, escribir libros––todas estas actividades son maneras
  de editar en un sentido mas amplio de la palabra.)

#   Although Emacs Lisp is usually thought of in association only with Emacs,
#   it is a full computer programming language. You can use Emacs Lisp as you
#   would any other programming language.
  Aunque Emacs Lisp normalmente se asocia solo con Emacs, es un lenguaje de
  programación completo. Se puede usar Emacs Lisp del mismo modo que con
  cualquier otro lenguaje de programación.

#   Perhaps you want to understand programming; perhaps you want to extend
#   Emacs; or perhaps you want to become a programmer. This introduction to
#   Emacs Lisp is designed to get you started: to guide you in learning the
#   fundamentals of programming, and more importantly, to show you how you can
#   teach yourself to go further.
  Quizás quieras entender la programación; quizás quieras extender Emacs; o
  tal vez quieras convertirte en un programador. Esta introducción a Emacs Lisp está
  diseñada para que empieces: para guiarte en el aprendizaje de los fundamentos
  de la programación y, lo que es más importante, para mostrarte como puedes
  aprender a ir mas más allá.

# ** On Reading this Text
** Sobre la lectura de este texto

#    All through this document, you will see little sample programs you can run
#    inside of Emacs. If you read this document in Info inside of GNU Emacs,
#    you can run the programs as they appear.  (This is easy to do and is
#    explained when the examples are presented.)  Alternatively, you can read
#    this introduction as a printed book while sitting beside a computer
#    running Emacs.  (This is what I like to do; I like printed books.)  If you
#    don't have a running Emacs beside you, you can still read this book, but
#    in this case, it is best to treat it as a novel or as a travel guide to a
#    country not yet visited: interesting, but not the same as being there.
   A lo largo de este documento, verás pequeños programas de ejemplo que se
   pueden ejecutar dentro de Emacs. Si lees este documento dentro de GNU Emacs,
   puedes ejecutar los programas tal y como aparecen. (Esto es fácil de hacer y
   se explica cuando se presentan los ejemplos). Alternativamente, puedes leer
   esta introducción como un libro impreso mientras se está sentando frente a un
   ordenador ejecutando Emacs. (Esto es lo que me gusta hacer; me gustan los
   libros impresos.) Si no tienes un Emacs funcionando a tu lado, todavía
   puedes leer este libro, pero en este caso, lo mejor es tratarlo como una
   novela, o como una guía de viaje a un país que aún no visitas: interesante,
   pero no es lo mismo que estar allí.

#    Much of this introduction is dedicated to walkthroughs or guided tours of
#    code used in GNU Emacs. These tours are designed for two purposes: first,
#    to give you familiarity with real, working code (code you use every day);
#    and, second, to give you familiarity with the way Emacs works. It is
#    interesting to see how a working environment is implemented. Also, I hope
#    that you will pick up the habit of browsing through source code. You can
#    learn from it and mine it for ideas. Having GNU Emacs is like having a
#    dragon's cave of treasures.
   Gran parte de esta introducción esta dedicada a recorridos o visitas guiadas
   del código usado en GNU Emacs. Estos recorridos están diseñados para dos
   propósitos: primero, para que te familiarices con el código de trabajo real
   (código que se usa cada día); y, segundo, para que te familiarices con el
   funcionamiento de Emacs. Es interesante ver cómo se implementa un entorno de
   trabajo completamente operativo. Ademas, espero que adquieras el hábito de
   navegar a través del código fuente. Puedes aprender mucho comparando código
   de otros con el propio y extraer nuevas ideas. Tener GNU Emacs es como tener
   la cueva del dragón de los tesoros.

#    In addition to learning about Emacs as an editor and Emacs Lisp as a
#    programming language, the examples and guided tours will give you an
#    opportunity to get acquainted with Emacs as a Lisp programming
#    environment. GNU Emacs supports programming and provides tools that you
#    will want to become comfortable using, such as @k{M-.} (the key which
#    invokes the @c{find-tag} command). You will also learn about buffers and
#    other objects that are part of the environment. Learning about these
#    features of Emacs is like learning new routes around your home town.
   Además de aprender sobre Emacs como editor y Emacs Lisp como lenguaje de
   programación, los ejemplos y visitas guiadas te darán una oportunidad para
   familiarizarte con Emacs como entorno de programación Lisp. GNU Emacs
   soporta programación y provee herramientas que llegaras a sentirte comodo
   usando, como @k{M-.} (el atajo que invoca el comando @c{find-tag}). También
   aprenderas sobre los búfers y otros objetos que forman parte del entorno.
   Aprender estas caracteristicas de Emacs es como aprender nuevas rutas
   alrededor de tu ciudad natal.

#    Finally, I hope to convey some of the skills for using Emacs to learn
#    aspects of programming that you don't know. You can often use Emacs to
#    help you understand what puzzles you or to find out how to do something
#    new. This self-reliance is not only a pleasure, but an advantage.
   Finalmente, espero poder transmitirte algunas habilidades para utilizar
   Emacs con el fin de aprender aspectos de programación que no conoces. Con
   frecuencia se puede usar Emacs como ayuda para entender un rompecabezas o
   para encontrar la manera de hacer algo nuevo. Este auto-descubrimiento no
   es solo un placer, también es una ventaja.

# ** For Whom This is Written
** Para quien está escrito esto

#    This text is written as an elementary introduction for people who are not
#    programmers. If you are a programmer, you may not be satisfied with this
#    primer. The reason is that you may have become expert at reading
#    reference manuals and be put off by the way this text is organized.
   Este texto está escrito como una introducción elemental para personas que no
   son programadoras. Si eres es un programador, es posible que no estes
   satisfecho con este manual. La razón es que un programador puede tener que
   convertirse en experto leyendo manuales de referencia y este texto no está
   organizado como un manual de referencia.

#    An expert programmer who reviewed this text said to me:
   Un programador experto que revisó este texto me dijo:

#    ..quote >
   ..quote >
#      I prefer to learn from reference manuals. I “dive into” each
#      paragraph, and “come up for air” between paragraphs.
     Prefiero aprender desde manuales de referencia. Me “zambullo” en cada
     párrafo y “subo a tomar aire” entre párrafos.

#      When I get to the end of a paragraph, I assume that that subject is
#      done, finished, that I know everything I need (with the possible
#      exception of the case when the next paragraph starts talking about it in
#      more detail). I expect that a well written reference manual will not
#      have a lot of redundancy, and that it will have excellent pointers to
#      the (one) place where the information I want is.
     Cuando llego al fin de un párrafo, asumo que este asunto está hecho,
     terminado, que sé todo lo que necesito (con la posible excepción del caso
     en que el siguiente párrafo empiece a hablar de ello con más detalle). Espero
     que un manual de referencia bien escrito no tenga mucha redundancia, y que
     tenga excelentes indicadores del (unico) lugar donde está la información
     que quiero.
#    < quote..
   < quote..

#    This introduction is not written for this person!
   ¡Esta introducción no está escrita para esta persona!

#    Firstly, I try to say everything at least three times: first, to introduce
#    it; second, to show it in context; and third, to show it in a different
#    context, or to review it.
   En primer lugar, intento decir cada cosa al menos tres veces: primero, para
   introducirlo; segundo, para mostrarlo en contexto; y tercero, para mostrarlo
   en un contexto diferente, o revisarlo.

#    Secondly, I hardly ever put all the information about a subject in one
#    place, much less in one paragraph. To my way of thinking, that imposes
#    too heavy a burden on the reader. Instead I try to explain only what you
#    need to know at the time.  (Sometimes I include a little extra information
#    so you won't be surprised later when the additional information is
#    formally introduced.)
   En segundo lugar, casi nunca pongo toda la información sobre un tema en un
   solo lugar, y mucho menos en un párrafo. A mi manera de pensar, eso impone
   una carga bastante pesada al lector. En cambio, trato de explicar solo lo
   que necesitas saber en ese momento. (Algunas veces incluyo una pequeña
   información extra, para que no haya sorpresas más tarde cuando la información
   adicional sea presentada formalmente.)

#    When you read this text, you are not expected to learn everything the
#    first time. Frequently, you need only make, as it were, a ‘nodding
#    acquaintance’ with some of the items mentioned. My hope is that I have
#    structured the text and given you enough hints that you will be alert to
#    what is important, and concentrate on it.
   Cuando leas este texto, no se esperes aprender todo la primera vez.
   Frecuentemente, solo necesitas, por asi decirlo, un ‘asentir con la cabeza’
   en alguno de los articulos mencionados. Mi esperanza es haber estructurado el
   texto y dar suficientes pistas para indicar lo que es importante y
   te concentres en ello.

#    You will need to “dive into” some paragraphs; there is no other way to
#    read them. But I have tried to keep down the number of such paragraphs.
#    This book is intended as an approachable hill, rather than as a daunting
#    mountain.
   Necesitaras “sumergirte” en algunos párrafos; no hay otro modo de
   leerlos. Pero he intentado reducir el número de esos párrafos. Este libro
   pretende ser como una colina accesible, mas que una montaña abrumadora.

#    This introduction to @e{Programming in Emacs Lisp} has a companion
#    document, @e{The GNU Emacs Lisp Reference Manual}. The reference manual
#    has more detail than this introduction. In the reference manual, all the
#    information about one topic is concentrated in one place. You should turn
#    to it if you are like the programmer quoted above. And, of course, after
#    you have read this @e{Introduction}, you will find the @e{Reference
#    Manual} useful when you are writing your own programs.
   Esta introducción a la @e{Programación en Emacs Lisp} tiene un documento
   complementario. @e{El Manual de Referencia de GNU Emacs Lisp}. El manual de
   referencia tiene más detalles que esta introducción. En el manual de
   referencia, toda la información sobre un tema se concentra en un solo
   lugar. Deberias recurrir a el si eres como el programador citado
   anteriormente. Y, por supuesto, después de haber leido esta @e{Introducción},
   encontraras el @e{Manual de Referencia} util cuando escribas tus propios
   programas.

# ** Lisp History
** Historia de Lisp

#    Lisp was first developed in the late 1950s at the Massachusetts Institute
#    of Technology for research in artificial intelligence. The great power of
#    the Lisp language makes it superior for other purposes as well, such as
#    writing editor commands and integrated environments.
   Lisp fué originariamente desarrollado a finales de los años 50 en el
   Instituto Tecnológico de Massachusetts para la investigacion en inteligencia
   artificial. El gran poder del lenguaje Lisp lo hace superior también para
   otros propósitos, como la escritura de comandos de edición y entornos
   integrados.

#    GNU Emacs Lisp is largely inspired by Maclisp, which was written at MIT in
#    the 1960s. It is somewhat inspired by Common Lisp, which became a
#    standard in the 1980s. However, Emacs Lisp is much simpler than Common
#    Lisp. (The standard Emacs distribution contains an optional extensions
#    file, @f{cl.el}, that adds many Common Lisp features to Emacs Lisp.)
   GNU Emacs Lisp está fuertemente inspirado en Maclisp, que fue escrito en el
   MIT en la decada de 1960. Está en cierto modo inspirado en Common Lisp, que
   se convirtio en un estándar en los 80. Sin embargo, Emacs Lisp es mucho más
   simple que Common Lisp. (La distribución estándar de Emacs contiene un
   fichero de extensiones opcional, @f{cl.el}, que añade muchas caracteristicas
   de Common Lisp a Emacs Lisp.)

# ** Note for Novices
** Nota para los principiantes

#    If you don't know GNU Emacs, you can still read this document profitably.
#    However, I recommend you learn Emacs, if only to learn to move around your
#    computer screen. You can teach yourself how to use Emacs with the on-line
#    tutorial. To use it, type @k{C-h t}. (This means you press and release
#    the @k{CTRL} key and the @k{h} at the same time, and then press and
#    release @k{t}.)
   Si no conoces GNU Emacs, todavia puedes leer este documento
   provechosamente. Sin embargo, te recomiendo que aprendas Emacs, al menos
   aprender a moverte alrededor de la pantalla del ordenador. Puedes aprender
   por ti mismo como usar Emacs con el tutorial incorporado. Para usarlo,
   escribe @k{C-h t}. (Esto significa que debes presionar la tecla @k{CTRL}
   y la @k{h} al mismo tiempo, y luego presionar y soltar @k{t}).

#    Also, I often refer to one of Emacs's standard commands by listing the
#    keys which you press to invoke the command and then giving the name of the
#    command in parentheses, like this: @k{M-C-\} @%c(indent-region). What
#    this means is that the @c{indent-region} command is customarily invoked by
#    typing @k{M-C-\}. (You can, if you wish, change the keys that are typed
#    to invoke the command; this is called @:{rebinding}. See Section
#    @l{#Keymaps}.) The abbreviation @k{M-C-\} means that you type your
#    @k{META} key, @k{CTRL} key and @k{\} key all at the same time.  (On many
#    modern keyboards the @k{META} key is labeled @k{ALT}.)  Sometimes a
#    combination like this is called a keychord, since it is similar to the way
#    you play a chord on a piano. If your keyboard does not have a @k{META}
#    key, the @k{ESC} key prefix is used in place of it. In this case,
#    @k{M-C-\} means that you press and release your @k{ESC} key and then type
#    the @k{CTRL} key and the @k{\} key at the same time. But usually
#    @k{M-C-\} means press the @k{CTRL} key along with the key that is labeled
#    @k{ALT} and, at the same time, press the @k{\} key.
   Ademas, a menudo me refiero a uno de los comandos estándar de Emacs listando
   las teclas que se presionan para invocar el comando y, luego dando el nombre
   del comando entre paréntesis, asi: @k{M-C-\} (@c{indent-region}). Esto
   significa invocar el comando @c{indent-region} presionando @k{M-C-\}. (Puedes,
   Si lo deseas, cambiar las teclas que se presionan para invocar el comando;
   esto se denomina @:{rebinding}. Consulta la Sección @l{#Mapas de teclado}.)
   La abreviatura @k{M-C-\} significa que debes presionar la tecla @k{META},
   @k{CTRL}, y @k{\} al mismo tiempo. (En muchos teclados modernos la tecla
   @k{META} se llama @k{ALT}.)  Algunas veces una combinación como esta
   se llama un @e{acorde de teclas}, puesto que es similar a tocar un acorde en un
   piano. Si el teclado no tiene una tecla @k{META}, en su lugar se usa la tecla
   @k{ESC} como prefijo. En este caso @k{M-C-\} significa que se presiona y
   libera @k{ESC} y luego se presionan la tecla @k{CTRL} y la tecla @k{\} al mismo
   tiempo. Pero normalmente @k{M-C-\} significa presionar la tecla @k{CTRL}
   junto a la tecla que está marcada como @k{ALT} y, al mismo tiempo, presionar
   la tecla @k{\}.

#    In addition to typing a lone keychord, you can prefix what you type with
#    @k{C-u}, which is called the ‘universal argument’. The @k{C-u} keychord
#    passes an argument to the subsequent command. Thus, to indent a region of
#    plain text by 6 spaces, mark the region, and then type @k{C-u 6 M-C-\}.
#    (If you do not specify a number, Emacs either passes the number 4 to the
#    command or otherwise runs the command differently than it would
#    otherwise.)  See Section @l{emacs.html#Arguments<>Numeric Arguments} in
#    @e(The GNU Emacs Manual).
   Además de pulsar una sola combinación de teclas, puedes prefijar lo que
   escribes con @k{C-u}, que se llama el ‘argumento universal’. El atajo @k{C-u}
   pasa un argumento al siguiente comando. Por lo tanto, para indentar una
   región de texto plano por 6 espacios, marca la región, y lugo presiona @k{C-u
   6 M-C-\}. (Si no se especifica un número, Emacs pasa el número 4 al comando o
   ejecuta el comando de forma diferente a como lo haria de otro modo). Consulta
   la Sección @l{emacs.html#Arguments<>Argumentos
   Numéricos} en @e{El Manual de GNU Emacs}.

#    If you are reading this in Info using GNU Emacs, you can read through this
#    whole document just by pressing the space bar, @k{SPC}.  (To learn about
#    Info, type @k{C-h i} and then select Info.)
   Si estás leyendo esto en Info usando GNU Emacs, puedes avanzar a través de
   todo este documento presionando la barra espaciadora, @k{SPC}. (Para
   aprender acerca de Info, presiona @k{C-h i} y luego selecciona Info.)

#    A note on terminology: when I use the word Lisp alone, I often am
#    referring to the various dialects of Lisp in general, but when I speak of
#    Emacs Lisp, I am referring to GNU Emacs Lisp in particular.
   Una nota sobre terminología: cuando uso la palabra Lisp sola, con frecuencia
   me estoy refiriendo a los diversos dialectos de Lisp en general, pero cuando
   hablo de Emacs Lisp, me estoy refiriendo a GNU Emacs Lisp en particular.

# ** Thank You
** Agradecimientos

#    My thanks to all who helped me with this book. My especial thanks to Jim
#    Blandy, Noah Friedman, Jim Kingdon, Roland McGrath, Frank Ritter, Randy
#    Smith, Richard M. Stallman, and Melissa Weisshaus. My thanks also go to
#    both Philip Johnson and David Stampe for their patient encouragement. My
#    mistakes are my own.
   Estoy agradecido a todos los que me ayudaron con este libro. Mi
   especial agradecimiento a Jim Blandy, Noah Friedman, Jim Kingdon, Roland
   McGrath, Frank Ritter, Randy Smith, Richard M. Stallman, y Melissa
   Weisshaus. Gracias también a Philip Johnson y David Stampe por su paciente
   aliento. Mis errores son míos.

#    ..right >
#      Robert J. Chassell @l{mailto:bob@@gnu.org}
   ..right >
     Robert J. Chassell @l{mailto:bob@@gnu.org}

# * List Processing
* Procesamiento de listas

#   To the untutored eye, Lisp is a strange programming language. In Lisp code
#   there are parentheses everywhere. Some people even claim that the name
#   stands for ‘Lots of Isolated Silly Parentheses’. But the claim is
#   unwarranted. Lisp stands for LISt Processing, and the programming language
#   handles @e{lists} (and lists of lists) by putting them between parentheses.
#   The parentheses mark the boundaries of the list. Sometimes a list is
#   preceded by a single apostrophe or quotation mark, @'{'}@n{1}. Lists are the
#   basis of Lisp.
  Para el ojo inexperto, Lisp es un lenguaje de programación extraño. En
  código Lisp hay paréntesis por todas partes. Algunas personas incluso
  afirman que el nombre signfica ‘Lots of Isolated Silly Parentheses’
  (‘Montones de Paréntesis Aislados Estúpidos’). Pero el reclamo es
  injustificado. Lisp significa LISt Processing, y el lenguaje de
  programación maneja @e{listas} (y listas de listas) poniéndolas entre
  paréntesis. Los paréntesis marcan los límites de la lista. Algunas veces
  una lista va precedida por un apóstrofe simple o una marca de cita,
  @'{'}@n{1}. Las listas son el fundamento de Lisp.

# ** Lisp Lists
** Listas Lisp

#    In Lisp, a list looks like this: @c{'(rose violet daisy buttercup)}. This
#    list is preceded by a single apostrophe. It could just as well be written
#    as follows, which looks more like the kind of list you are likely to be
#    familiar with:
   En Lisp, una lista tiene el siguiente aspecto: @c{'(rosa violeta margarita
   tulipan)}.  Esta lista es precedida por una comilla. Bien, podría estar
   escrita de la siguiende manera, que se parece mas al tipo de lista con la que
   probablemente estes familiarizado:

#    ..src > elisp
#      '(rose
#        violet
#        daisy
#        buttercup)
#    < src..
   ..src > elisp
     '(rosa
       violeta
       margarita
       tulipan)
   < src..

#    The elements of this list are the names of the four different flowers,
#    separated from each other by whitespace and surrounded by parentheses,
#    like flowers in a field with a stone wall around them.
   Los elementos de esta lista son los nombres de 4 flores diferentes,
   separados por espacios en blanco y rodeados de paréntesis, como flores en
   un campo con un muro de piedras a su alrededor.

#    Lists can also have numbers in them, as in this list: @c{(+ 2 2)}. This
#    list has a plus-sign, @'{+}, followed by two @'{2}s, each separated by
#    whitespace.
   Las listas también pueden tener números, como en esta lista: @c{(+
   2 2)}. Esta lista tiene un signo más, @'{+}, seguido por dos @'{2}, cada
   uno separado por espacios en blanco.

#    In Lisp, both data and programs are represented the same way; that is,
#    they are both lists of words, numbers, or other lists, separated by
#    whitespace and surrounded by parentheses.  (Since a program looks like
#    data, one program may easily serve as data for another; this is a very
#    powerful feature of Lisp.)  (Incidentally, these two parenthetical remarks
#    are @e{not} Lisp lists, because they contain @'{;} and @'{.} as
#    punctuation marks.)
   En Lisp, tanto datos como programas se representan de la misma manera; es
   decir, son a la vez listas de palabras, números, u otras listas, separadas
   por espacios en blanco y rodeadas de paréntesis. (Puesto que un programa se
   parece a los datos, un programa puede servir fácilmente como datos para
   otros; esta es un caracteristica muy poderosa de Lisp.)  (A proposito, estas
   dos marcas de paréntesis @e{no} son listas Lisp, porque contienen @'{;} y
   @'{.} como signos de puntuación.)

#    Here is another list, this time with a list inside of it:
   Aquí hay otra lista, esta vez con una lista dentro de ella:

#    ..src > elisp
#      '(this list has (a list inside of it))
#    < src..
   ..src > elisp
     '(esta lista tiene (una lista dentro de ella))
   < src..

#    The components of this list are the words @'c{this}, @'c{list}, @'c{has}, and
#    the list @'c{(a list inside of it)}. The interior list is made up of the
#    words @'c{a}, @'c{list}, @'c{inside}, @'c{of}, @'c{it}.
   Los componentes de esta lista son las palabras @'c{esta}, @'c{lista},
   @'c{tiene}, y la lista @'c{(una lista dentro de ella)}. La lista interior se
   construye con las palabras @'c{una}, @'c{lista}, @'c{dentro}, @'c{de},
   @'c{ella}.

# *** Lisp Atoms
*** Átomos Lisp

#     In Lisp, what we have been calling words are called @:{atoms}. This term
#     comes from the historical meaning of the word atom, which means
#     ‘indivisible’. As far as Lisp is concerned, the words we have been using
#     in the lists cannot be divided into any smaller parts and still mean the
#     same thing as part of a program; likewise with numbers and single
#     character symbols like @'{+}. On the other hand, unlike an ancient atom,
#     a list can be split into parts.  (See Section @l{#@c{car}, @c{cdr},
#     @c{cons}: Fundamental Functions}.)
    En Lisp, lo que hemos estado llamando palabras son en realidad
    @:{átomos}. Este término proviene del significado historico de la palabra
    átomo, que significa ‘indivisible’. En lo que a Lisp concierne, las palabras
    que hemos estado usando en las listas no se pueden dividir en partes mas
    pequeñas, sin perder su significado dentro del programa; lo mismo ocurre con
    números y símbolos de un caracterer como @'{+}. Por otro lado, a diferencia
    de un átomo antiguo, una lista puede dividirse en partes. Consulta la seccion
    @l(#@c{car}, @c{cdr}, @c{cons}: Funciones fundamentales).

#     In a list, atoms are separated from each other by whitespace. They can
#     be right next to a parenthesis.
    En una lista, los átomos se separan unos de otros por espacios en blanco.
    Pueden estar justo al lado de un paréntesis.

#     Technically speaking, a list in Lisp consists of parentheses surrounding
#     atoms separated by whitespace or surrounding other lists or surrounding
#     both atoms and other lists. A list can have just one atom in it or have
#     nothing in it at all. A list with nothing in it looks like this: @c{()},
#     and is called the @:{empty list}. Unlike anything else, an empty list is
#     considered both an atom and a list at the same time.
    Técnicamente hablando, una lista en Lisp consiste en paréntesis que rodean
    átomos separados por espacios en blanco o alrededor de otras lista o
    alrededor de ambos átomos y otras listas. Una lista puede tener solo un
    átomo o no tener absolutamente nada en ella. Una lista con nada dentro se
    ve así: @c{()}, y se llama @:{lista vacía}. A diferencia de cualquier otra
    cosa, una lista vacía es tanto un átomo, como una lista al mismo tiempo.

#     The printed representation of both atoms and lists are called @:{symbolic
#     expressions} or, more concisely, @:{s-expressions}. The word
#     @:{expression} by itself can refer to either the printed representation,
#     or to the atom or list as it is held internally in the computer. Often,
#     people use the term @:{expression} indiscriminately.  (Also, in many
#     texts, the word @:{form} is used as a synonym for expression.)
    La representación impresa de átomos y listas se llaman @:{expresiones
    simbólicas} o, más concisamente, @:{expresiones-s}. La palabra @:{expresión}
    por sí misma puede referirse o bien a la representación impresa, o al átomo o
    a la lista tal como se encuentra internamente en el ordenador. Con
    frecuencia, la gente usan el término @:{expresión} indiscriminadamente.
    (Ademas, en muchos textos, la palabra @:{forma} se usa como un sinónimo de
    expresión.)

#     Incidentally, the atoms that make up our universe were named such when
#     they were thought to be indivisible; but it has been found that physical
#     atoms are not indivisible. Parts can split off an atom or it can fission
#     into two parts of roughly equal size. Physical atoms were named
#     prematurely, before their truer nature was found. In Lisp, certain kinds
#     of atom, such as an array, can be separated into parts; but the mechanism
#     for doing this is different from the mechanism for splitting a list. As
#     far as list operations are concerned, the atoms of a list are
#     unsplittable.
    Por cierto, los átomos que componen nuestro universo fueron nombrados asi
    cuando se pensaba que eran indivisibles; pero se ha descubierto que los
    átomos fisicos no son indivisibles. Las partes pueden dividir un átomo o
    puede fisionarse en 2 partes de igual tamaño. Los átomos físicos se
    nombraron prematuramente, antes de que su verdadera naturaleza fuese
    encontrada. En Lisp, ciertos tipos de átomos, como un array, pueden ser
    separados en partes; pero el mecanismo de hacer esto es diferente del
    mecanismo para dividir una lista. En lo que se refiere a las operaciones de
    lista, los átomos de una lista son indivisibles.

#     As in English, the meanings of the component letters of a Lisp atom are
#     different from the meaning the letters make as a word. For example, the
#     word for the South American sloth, the @'{ai}, is completely different
#     from the two words, @'{a}, and @'{i}.
    Al igual que en el español, el significado de las letras que componen un
    átomo Lisp difieren del significado de las letras compuestas como una
    palabra. Por ejemplo, la expresión @'{ay}, es completamente diferente de las
    dos palabras @'{a}, e @'{y}.

#     There are many kinds of atom in nature but only a few in Lisp: for
#     example, @:{numbers}, such as 37, 511, or 1729, and @:{symbols}, such as
#     @'{+}, @'{foo}, or @'{forward-line}. The words we have listed in the
#     examples above are all symbols. In everyday Lisp conversation, the word
#     “atom” is not often used, because programmers usually try to be more
#     specific about what kind of atom they are dealing with. Lisp programming
#     is mostly about symbols (and sometimes numbers) within lists.
#     (Incidentally, the preceding three word parenthetical remark is a proper
#     list in Lisp, since it consists of atoms, which in this case are symbols,
#     separated by whitespace and enclosed by parentheses, without any non-Lisp
#     punctuation.)
    Hay muchos tipos de átomos en la naturaleza, pero solo unos pocos en Lisp:
    por ejemplo, los @:{números}, como 37, 511, o 1729, y los @:{símbolos}, como
    @'{+}, @'{foo}, o @'{forward-line}. Las palabras que hemos listado en los
    ejemplos anteriores son todos símbolos. En las conversaciones cotidianas de
    Lisp, la palabra “átomo” no se usa con frecuencia, porque los programadores
    normalmente intentan ser más específicos acerca del tipo de átomo que están
    tratando. La programación Lisp es mayormente sobre símbolos (y algunas veces
    números) dentro de listas. (De ese modo, tres palabras rodeadas de paréntesis son
    una lista apropiada en Lisp, ya que consiste de átomos, que en este caso son
    símbolos, separados por espacios en blanco y encerrados entre paréntesis, sin
    ninguna puntuacion ajena a Lisp.)

#     Text between double quotation marks––even sentences or paragraphs––is
#     also an atom. Here is an example:
    El texto entre comillas––incluso oraciones o párrafos––son también un átomo.
    Aquí hay un ejemplo:

#     ..src > elisp
#       '(this list includes "text between quotation marks.")
#     < src..
    ..src > elisp
      '(esta lista incluye "texto entre comillas.")
    < src..

#     In Lisp, all of the quoted text including the punctuation mark and the
#     blank spaces is a single atom. This kind of atom is called a @:{string}
#     (for ‘string of characters’) and is the sort of thing that is used for
#     messages that a computer can print for a human to read. Strings are a
#     different kind of atom than numbers or symbols and are used differently.
    En Lisp, todo el texto entre comillas, incluyendo la marca de puntuación y los
    espacios en blanco, son un unico átomo. Este tipo de átomo se llama
    @:{string} @%i(cadena), por ‘cadena de caracteres’) y es el tipo de cosa que
    se utiliza para los mensajes que un ordenador puede imprimir para que los
    lea un humano. Las cadenas son un tipo de átomo diferente a los números, o
    símbolos y se usan de manera diferente.

# *** Whitespace in Lists
*** Espacios en blanco en las listas

#     The amount of whitespace in a list does not matter. From the point of
#     view of the Lisp language,
    La cantidad de espacios en blanco en una lista no importa. Desde el punto
    de vista del lenguaje Lisp,

#     ..src > elisp
#       '(this list
#          looks like this)
#     < src..
    ..src > elisp
      '(esta lista
         se ve asi)
    < src..

#     is exactly the same as this:
    es exactamente lo mismo que esto:

#     ..src > elisp
#       '(this list looks like this)
#     < src..
    ..src > elisp
      '(esta lista se ve asi)
    < src..

#     Both examples show what to Lisp is the same list, the list made up of the
#     symbols @'c{this}, @'c{list}, @'c{looks}, @'c{like}, and @'c{this} in that
#     order.
    Ambos ejemplos muestran lo que para Lisp es la misma lista, la lista compuesta
    por los símbolos @'c{esta}, @'c{lista}, @'c{se}, @'c{ve}, y @'c{asi} en ese orden.

#     Extra whitespace and newlines are designed to make a list more readable
#     by humans. When Lisp reads the expression, it gets rid of all the extra
#     whitespace (but it needs to have at least one space between atoms in
#     order to tell them apart.)
    Los espacios en blanco adicionales y los saltos de línea están diseñados
    para crear una lista más legible para los humanos. Cuando Lisp lee la
    expresión, se deshace de todos los espacios en blanco adicionales (pero necesita tener
    al menos un espacio entre los átomos para poder distinguirlos.)

#     Odd as it seems, the examples we have seen cover almost all of what Lisp
#     lists look like!  Every other list in Lisp looks more or less like one of
#     these examples, except that the list may be longer and more complex. In
#     brief, a list is between parentheses, a string is between quotation
#     marks, a symbol looks like a word, and a number looks like a number.
#     (For certain situations, square brackets, dots and a few other special
#     characters may be used; however, we will go quite far without them.)
    Por extraño que parezca, los ejemplos que hemos visto cubren casi todos los
    aspectos de las listas de Lisp. Cualquier otra lista en Lisp se ve más o
    menos igual a uno de estos ejemplos, excepto que la lista puede ser más
    larga y compleja. En resumen, una lista está entre paréntesis, una cadena
    entre comillas, un símbolo se parece a una palabra, y un número a un
    número. (Para ciertas situaciones, es pueden utilizar corchetes, puntos y
    otros caracteres especiales; sin embargo; iremos bastante lejos sin ellos.)

# *** GNU Emacs Helps You Type Lists
*** GNU Emacs te ayuda a escribir listas

#     When you type a Lisp expression in GNU Emacs using either Lisp
#     Interaction mode or Emacs Lisp mode, you have available to you several
#     commands to format the Lisp expression so it is easy to read. For
#     example, pressing the @k{TAB} key automatically indents the line the
#     cursor is on by the right amount. A command to properly indent the code
#     in a region is customarily bound to @k{M-C-\}. Indentation is designed
#     so that you can see which elements of a list belong to which
#     list––elements of a sub-list are indented more than the elements of the
#     enclosing list.
    Cuando se escribe una expresión Lisp en GNU Emacs usando el modo de
    Interacción Lisp o el modo Emacs Lisp, están disponibles varios comandos
    para formatear la expresión Lisp, de modo que sea fácil de leer. Por
    ejemplo, presionando la tecla @k{TAB} automáticamente se indenta la línea
    donde se encuentra el cursor a la cantidad correcta. Un comando para indentar
    apropiadamente el código en una región suele vincularse a @k{M-C-\}. La
    indentación está diseñada de modo que se pueda ver qué elementos pertenecen a
    cada lista––los elementos de una sublista están más indentados que los
    elementos de la lista adjunta.

#     In addition, when you type a closing parenthesis, Emacs momentarily jumps
#     the cursor back to the matching opening parenthesis, so you can see which
#     one it is. This is very useful, since every list you type in Lisp must
#     have its closing parenthesis match its opening parenthesis.  (See Section
#     @l{emacs.html#Major Modes<>Major Modes} in @e(The GNU Emacs Manual), for
#     more information about Emacs's modes.)
    Además, al escribir un paréntesis de cierre, Emacs mueve el cursor
    momentáneamente hacia el parentesis de apertura correspondiente, para que
    puedas ver cual es. Esto es muy útil, ya que cada lista que escribas en
    Lisp debe tener su paréntesis de cierre que coincida con su paréntesis de
    apertura. (Consulta la Seccion @l{emacs.html#Major
    Modes<>Modos Mayores} en @e{El Manual de GNU Emacs}, para más información
    sobre los modos de Emacs.)

# ** Run a Program
** Ejecutar un programa

#    A list in Lisp––any list––is a program ready to run. If you run it (for
#    which the Lisp jargon is @:{evaluate}), the computer will do one of three
#    things: do nothing except return to you the list itself; send you an error
#    message; or, treat the first symbol in the list as a command to do
#    something.  (Usually, of course, it is the last of these three things that
#    you really want!)
   Una lista en Lisp––cualquier lista––es un programa listo para ejecutarse. Si
   lo ejecutas (lo que la jerga Lisp llama @:{evaluar}), el ordenador hará una
   de tres cosas: nada excepto devolverte la lista misma; enviar un mensaje de
   error; o, tomar el primer símbolo en la lista como un comando para hacer
   alguna cosa. (¡Normalmente, por supuesto, es la última de estas tres cosas lo
   que realmente quieres!).

#    The single apostrophe, @c{'}, that I put in front of some of the example
#    lists in preceding sections is called a @:{quote}; when it precedes a
#    list, it tells Lisp to do nothing with the list, other than take it as it
#    is written. But if there is no quote preceding a list, the first item of
#    the list is special: it is a command for the computer to obey.  (In Lisp,
#    these commands are called @e{functions}.)  The list @c{(+ 2 2)} shown
#    above did not have a quote in front of it, so Lisp understands that the
#    @c{+} is an instruction to do something with the rest of the list: add the
#    numbers that follow.
   El apóstrofe, @c{'}, que puse delante de algunas de las listas de ejemplo en
   las secciones anteriores se llama @:{quote} (citar); cuando precede a una
   lista, le dice a Lisp que no haga nada con la lista, mas que tomarla tal
   como está escrita. Pero si no hay una cita precediendo la lista, el primer
   elemento de la lista es especial: es un comando que el ordenador debe
   obedecer. (En Lisp, estos comandos se llaman @e{funciones}.) La lista @c[(+ 2
   2)] mostrada a continuación no tiene una cita delante de ella, por lo que
   Lisp comprende que @c{+} es una instrucción para hacer alguna cosa con el
   resto de la lista: sumar los números que siguen.

#    If you are reading this inside of GNU Emacs in Info, here is how you can
#    evaluate such a list: place your cursor immediately after the right hand
#    parenthesis of the following list and then type @k{C-x C-e}:
   Si estás leyendo esto dentro de GNU Emacs, aquí está como puedes evaluar
   tal lista: coloca tu cursor justo después del paréntesis derecho de la
   siguiente lista y presiona @k{C-x C-e}:

#    ..src > elisp
#      (+ 2 2)
#    < src..
   ..src > elisp
     (+ 2 2)
   < src..

#    You will see the number @c{4} appear in the echo area.  (In the jargon,
#    what you have just done is “evaluate the list.”  The echo area is the line
#    at the bottom of the screen that displays or “echoes” text.)  Now try the
#    same thing with a quoted list: place the cursor right after the following
#    list and type @k{C-x C-e}:
   Verás que el número @c{4} aparece en el área eco. (En la jerga, lo que
   acabas de hacer es “evaluar la lista.” El área de eco es la línea en la
   parte inferior de la pantalla que muestra o hace “eco” del texto.) Ahora
   intenta lo mismo con una lista con cita: coloca el cursor
   justo después de la siguiente lista y presiona @k{C-x C-e}:

#    ..src > elisp
#      '(this is a quoted list)
#    < src..
   ..src > elisp
     '(esto es una lista citada)
   < src..

#    You will see @c{(this is a quoted list)} appear in the echo area.
   Verás aparecer @c{(esto es una lista citada)} en el área eco.

#    In both cases, what you are doing is giving a command to the program
#    inside of GNU Emacs called the @:{Lisp interpreter}––giving the
#    interpreter a command to evaluate the expression. The name of the Lisp
#    interpreter comes from the word for the task done by a human who comes up
#    with the meaning of an expression––who “interprets” it.
   En ambos casos, lo que estás haciendo es dar un comando al programa dentro
   de GNU Emacs llamado @:{intérprete Lisp}––dando al intérprete un comando
   para evaluar la expresión. El nombre del intérprete Lisp viene de la
   palabra para la tarea realizada por un humano que viene con el significado de
   una expresión––quien lo “interpreta”.

#    You can also evaluate an atom that is not part of a list––one that is not
#    surrounded by parentheses; again, the Lisp interpreter translates from the
#    humanly readable expression to the language of the computer. But before
#    discussing this (see Section @l{#Variables}), we will discuss what the Lisp
#    interpreter does when you make an error.
   También puedes evaluar un átomo que no es parte de una lista––uno que no
   está rodeado por paréntesis; una vez mas, el intérprete Lisp traduce desde la
   expresión humanamente legible al lenguaje del ordenador. Pero antes de
   discutir esto (consulta la Seccion @l{#Variables}), veremos lo que hace
   intérprete de Lisp cuando cometes un el error.

# ** Generate an Error Message
** Generar un mensaje de error

#    Partly so you won't worry if you do it accidentally, we will now give a
#    command to the Lisp interpreter that generates an error message. This is
#    a harmless activity; and indeed, we will often try to generate error
#    messages intentionally. Once you understand the jargon, error messages
#    can be informative. Instead of being called “error” messages, they should
#    be called “help” messages. They are like signposts to a traveler in a
#    strange country; deciphering them can be hard, but once understood, they
#    can point the way.
   En parte para que no te preocupes si generas un mensaje de error de manera
   accidental, ahora daremos un comando al intérprete de Lisp que genera un
   mensaje de error.  Esta es una accion inofensiva; y de hecho, a menudo
   intentaremos generar mensajes de error de manera intencional. Una vez se entiende
   la jerga, los mensajes de error pueden ser informativos. En lugar de
   llamarse mensajes de “error”, deberían llamarse mensajes de “ayuda”. Son
   como señales para un viajero en un país extraño; descifrarlas puede ser
   dificil, pero una vez se comprenden, pueden señalar el camino.

#    The error message is generated by a built-in GNU Emacs debugger. We will
#    ‘enter the debugger’. You get out of the debugger by typing @c{q}.
   El mensaje de error es generado por un depurador de codigo incorporado dentro
   de GNU Emacs. Vamos a ‘entrar al depurador’. Para salir del depurador, presiona
   @c{q}.

#    What we will do is evaluate a list that is not quoted and does not have a
#    meaningful command as its first element. Here is a list almost exactly
#    the same as the one we just used, but without the single-quote in front of
#    it. Position the cursor right after it and type @k{C-x C-e}:
   Lo que vamos a hacer es evaluar una lista que no tiene cita y que no tiene un
   comando con significado como primer elemento. Aquí hay una lista casi
   exactamente igual a la que acabamos de usar, pero sin la cita al inicio.
   Coloca el cursor a la derecha donde esta finaliza y presiona @k{C-x C-e}:

#    ..src > elisp
#      (this is an unquoted list)
#    < src..
   ..src > elisp
     (esto es una lista sin cita)
   < src..

#    A @f{*Backtrace*} window will open up and you should see the following in
#    it:
   Se abrirá una ventana @f{*Backtrace*} y deberias ver lo siguiente:

#    ..example >
#      ---------- Buffer: *Backtrace* ----------
#      Debugger entered--Lisp error: (void-function this)
#        (this is an unquoted list)
#        eval((this is an unquoted list))
#        eval-last-sexp-1(nil)
#        eval-last-sexp(nil)
#        call-interactively(eval-last-sexp)
#      ---------- Buffer: *Backtrace* ----------
#    < example..
   ..example >
     ---------- Buffer: *Backtrace* ----------
     Debugger entered--Lisp error: (void-function esto)
       (esto es una lista sin cita)
       eval((esto es una lista sin cita) nil)
       eval-last-sexp-1(nil)
       eval-last-sexp(nil)
       call-interactively(eval-last-sexp nil nil)
       command-execute(eval-last-sexp)
     ---------- Buffer: *Backtrace* ----------
   < example..

#    Your cursor will be in this window (you may have to wait a few seconds
#    before it becomes visible). To quit the debugger and make the debugger
#    window go away, type: @k(q)
   Tu cursor estará en esta ventana (es posible que tengas que esperar unos
   pocos segundos antes de que se haga visible). Para salir del depurador y
   hacer que su ventana desaparezca, presiona: @k(q)

#    Please type @k{q} right now, so you become confident that you can get out
#    of the debugger. Then, type @k{C-x C-e} again to re-enter it.
   Por favor, ahora presiona @k{q}, para que puedas comprobar que se puede
   salir del depurador. A continuacion, presiona @k{C-x C-e} una vez mas para
   re-entrar.

#    Based on what we already know, we can almost read this error message.
   Basandonos en lo que ya sabemos, casi podemos leer este mensaje de error.

#    You read the @f{*Backtrace*} buffer from the bottom up; it tells you what
#    Emacs did. When you typed @k{C-x C-e}, you made an interactive call to
#    the command @c{eval-last-sexp}.  @c{eval} is an abbreviation for
#    ‘evaluate’ and @c{sexp} is an abbreviation for ‘symbolic expression’. The
#    command means ‘evaluate last symbolic expression’, which is the expression
#    just before your cursor.
   Leyendo el búfer @f{*Backtrace*} desde abajo hacia arriba; dice lo que hizo
   Emacs. Cuando presionaste @k{C-x C-e}, se hiso una llamada interactiva al
   comando @c{eval-last-sexp}. @c{eval} es una abreviatura para ‘evaluar’ y
   @c{sexp} es una abreviatura para ‘expresión simbólica’. El comando significa
   ‘evalúa la última expresión simbólica’, que es la expresión inmediatamente
   anterior al cursor.

#    Each line above tells you what the Lisp interpreter evaluated next. The
#    most recent action is at the top. The buffer is called the
#    @f{*Backtrace*} buffer because it enables you to track Emacs backwards.
   Cada linea sobre esta cuenta lo que el intérprete Lisp evaluo a continuacion. La
   acción más reciente está en la parte superior. El búfer se llama
   @f{*Backtrace*} por que permite realizar un seguimiento de Emacs hacia atrás.

#    At the top of the @f{*Backtrace*} buffer, you see the line:
   En la parte superior del búfer @f{*Backtrace*}, verás la línea:

#    ..example >
#      Debugger entered--Lisp error: (void-function this)
#    < example..
   ..example >
     Debugger entered--Lisp error: (void-function esto)
   < example..

#    The Lisp interpreter tried to evaluate the first atom of the list, the
#    word @'{this}. It is this action that generated the error message
#    @'{void-function this}.
   El intérprete Lisp intentó evaluar el primer átomo de la lista, la palabra
   @'{esto}. Es esta acción la que genero el mensaje de error @'{void-function
   esto}.

#    The message contains the words @'{void-function} and @'{this}.
   El mensaje contiene las palabras @'{void-function} y @'{esto}.

#    The word @'{function} was mentioned once before. It is a very important
#    word. For our purposes, we can define it by saying that a @:{function} is
#    a set of instructions to the computer that tell the computer to do
#    something.
   La palabra @'{function} @%i(función) fué mencionada antes. Es una palabra muy
   importante. Para nuestros propósitos, podemos definirla diciendo que una
   @:{función} es un conjunto de instrucciones para decirle al
   ordenador que haga alguna cosa.

#    Now we can begin to understand the error message: @'{void-function this}.
#    The function (that is, the word @'{this}) does not have a definition of
#    any set of instructions for the computer to carry out.
   Ahora podemos empezar a entender el mensaje de error: @'{void-function
   esto}. La función (es decir, la palabra @'{esto}) no tiene una definición de
   ningun conjunto de instrucciones que el ordenador pueda realizar.

#    The slightly odd word, @'{void-function}, is designed to cover the way
#    Emacs Lisp is implemented, which is that when a symbol does not have a
#    function definition attached to it, the place that should contain the
#    instructions is ‘void’.
   La palabra ligeramente extraña, @'{void-function}, está diseñada para cubrir
   la forma en que Emacs Lisp lo implementa, que es cuando un símbolo no tiene
   una definición de función adjunta, el sitio que contiene la instruccion esta
   ‘vacio’ @%i(void).

#    On the other hand, since we were able to add 2 plus 2 successfully, by
#    evaluating @c{(+ 2 2)}, we can infer that the symbol @c{+} must have a set
#    of instructions for the computer to obey and those instructions must be to
#    add the numbers that follow the @c{+}.
   Por otro lado, ya que fuimos capaces de sumar 2 más 2 de manera exitosa,
   evaluando @c{(+ 2 2)}, se puede inferir que el símbolo @c{+} debe tener un
   conjunto de instrucciones que el ordenador ejecuta y estas instrucciones
   deben ser para sumar los números despues del @c{+}.

#    It is possible to prevent Emacs entering the debugger in cases like this.
#    We do not explain how to do that here, but we will mention what the result
#    looks like, because you may encounter a similar situation if there is a
#    bug in some Emacs code that you are using. In such cases, you will see
#    only one line of error message; it will appear in the echo area and look
#    like this:
   Es posible evitar que Emacs entre en el depurador en casos como este. No se
   explicará cómo hacer esto aquí, pero mencionamos como se ve el resultado,
   porque puede que te encuentres con una situación similar si hay un error en
   algún código de Emacs que estes usando. En tales casos, solo verá una línea
   de mensaje de error; aparecera en el área de eco con el siguente aspecto:

#    ..example >
#      Symbol's function definition is void: this
#    < example..
   ..example >
     Symbol's function definition is void: esto
   < example..

#    The message goes away as soon as you type a key, even just to move the
#    cursor.
   El mensaje desaparece tan pronto se presione una tecla, aunque sólo sea para
   mover el cursor.

#    We know the meaning of the word @'{Symbol}. It refers to the first atom
#    of the list, the word @'{this}. The word @'{function} refers to the
#    instructions that tell the computer what to do.  (Technically, the symbol
#    tells the computer where to find the instructions, but this is a
#    complication we can ignore for the moment.)
   Conocemos el significado de la palabra @'{Symbol}. Se refiere al primer
   átomo de la lista, la palabra @'{esto}. La palabra @'{function} se refiere
   a las instrucciones que indican al ordenador que hacer. (Técnicamente, el
   símbolo le indica al ordenador donde encontrar las instrucciones, pero esta
   es una complicación que podemos ignorar por el momento.)

#    The error message can be understood: @'{Symbol's function definition is
#    void: this}. The symbol (that is, the word @'{this}) lacks instructions
#    for the computer to carry out.
   El mensaje de error es comprensible: @'{La definición del símbolo
   está vacía: esto}. El símbolo (que es, la palabra @'{esto}) carece de
   instrucciones para que el ordenador las lleve a cabo.

# ** Symbol Names and Function Definitions
** Nombres de símbolos y definiciones de funcion

#    We can articulate another characteristic of Lisp based on what we have
#    discussed so far––an important characteristic: a symbol, like @c{+}, is
#    not itself the set of instructions for the computer to carry out.
#    Instead, the symbol is used, perhaps temporarily, as a way of locating the
#    definition or set of instructions. What we see is the name through which
#    the instructions can be found. Names of people work the same way. I can
#    be referred to as @'{Bob}; however, I am not the letters @'{B}, @'{o},
#    @'{b} but am, or was, the consciousness consistently associated with a
#    particular life-form. The name is not me, but it can be used to refer to
#    me.
   Podemos articular otra característica de Lisp basada en lo que hemos
   discutido hasta ahora––una característica importante: un símbolo, como @c{+},
   no es en sí mismo el conjunto de instrucciones que el ordenador lleva a cabo. En
   su lugar, el símbolo se utiliza, quizás temporalmente, como una forma de
   localizar la definición o conjunto de instrucciones. Lo que vemos es el
   nombre con el cual se pueden encontrar las instrucciones. Los nombres de las
   personas funcionan de la misma manera. Por ejemplo puedo ser referido como
   @'{Bob}; sin embargo, no soy las letras @'{B}, @'{o}, @'{b} pero soy, o fuí,
   conscientemente asociado con una forma de vida en particular. El nombre no soy
   yo, pero puede ser usado para referirse a mi.

#    In Lisp, one set of instructions can be attached to several names. For
#    example, the computer instructions for adding numbers can be linked to the
#    symbol @c{plus} as well as to the symbol @c{+} (and are in some dialects
#    of Lisp). Among humans, I can be referred to as @'{Robert} as well as
#    @'{Bob} and by other words as well.
   En Lisp, un conjunto de instrucciones puede ligarse a varios nombres. Por
   ejemplo, las instrucciones para sumar números se pueden ligar al símbolo
   @c{mas} asi como al símbolo @c{+} (y se encuentran en algunos dialectos de
   Lisp). Entre los humanos, puede referirse a @'{Robert} tan bien como @'{Bob} y
   con otras palabras también.

#    On the other hand, a symbol can have only one function definition attached
#    to it at a time. Otherwise, the computer would be confused as to which
#    definition to use. If this were the case among people, only one person in
#    the world could be named @'{Bob}. However, the function definition to
#    which the name refers can be changed readily.  (See Section @l{#Install a
#    Function Definition}.)
   Por otra parte, un símbolo solo puede estar ligado con una definicion de
   función a la vez. De lo contrario, el ordenador estaría confundido en cuanto a
   qué definición usar. Si este fuera el caso entre las gente, solo una persona
   en el mundo podría llamarse @'{Bob}. Sin embargo, la definición de función a
   la que el nombre hace referencia puede cambiarse fácilmente. (Consulta la
   Sección @l{#Instalar una Definición de Función}.)

#    Since Emacs Lisp is large, it is customary to name symbols in a way that
#    identifies the part of Emacs to which the function belongs. Thus, all the
#    names for functions that deal with Texinfo start with @'c{texinfo-} and
#    those for functions that deal with reading mail start with @'c{rmail-}.
   Ya que Emacs Lisp es extenso, se acostumbra nombrar los símbolos de una
   forma que identifique la parte de Emacs a la que pertenece la función. En
   consecuencia, todos los nombres de funciones relacionadas con Texinfo
   comienzan con @'c{texinfo-} y aquellas relacionadas con la lectura de correo
   empiezan con @'c{rmail-}.

# ** The Lisp Interpreter
** El intérprete Lisp

#    Based on what we have seen, we can now start to figure out what the Lisp
#    interpreter does when we command it to evaluate a list. First, it looks
#    to see whether there is a quote before the list; if there is, the
#    interpreter just gives us the list. On the other hand, if there is no
#    quote, the interpreter looks at the first element in the list and sees
#    whether it has a function definition. If it does, the interpreter carries
#    out the instructions in the function definition. Otherwise, the
#    interpreter prints an error message.
   Basado en lo que hemos visto, ahora podemos empezar a entender lo que hace el
   intéprete Lisp cuando le ordenamos que evalue una lista. Primero, examina si
   hay un símbolo de cita antes de la lista; si lo hay, el intérprete solo nos da
   la lista. Por otra parte, si no hay cita, el intéprete mira si el primer
   elemento de la lista tiene una definición de función. De lo contrario, el
   intérprete imprime un mensaje de error.

#    This is how Lisp works. Simple. There are added complications which we
#    will get to in a minute, but these are the fundamentals. Of course, to
#    write Lisp programs, you need to know how to write function definitions
#    and attach them to names, and how to do this without confusing either
#    yourself or the computer.
   Así es como funciona Lisp. Simple. Hay complicaciones añadidas a las que
   llegaremos en un minuto, pero estos son los fundamentos. Por supuesto, para
   escribir programas Lisp, se necesita saber como escribir definiciones de
   función y vincularlas a nombres, y como hacer esto sin confundirnos a
   nosotros mismos o al ordenador.

#    Now, for the first complication. In addition to lists, the Lisp
#    interpreter can evaluate a symbol that is not quoted and does not have
#    parentheses around it. The Lisp interpreter will attempt to determine the
#    symbol's value as a @:{variable}. This situation is described in the
#    section on variables.  (See Section @l{#Variables}.)
   Ahora, una primera complicación. Además de las listas, el intérprete Lisp
   puede evaluar un símbolo sin citar y que no tiene paréntesis en torno a el. El
   intérprete intentará determinar el valor del símbolo como una @:{variable}.
   Esta situación se describe en el apartado de las variables. (Consulta la Seccion
   @l{#Variables}.)

#    The second complication occurs because some functions are unusual and do
#    not work in the usual manner. Those that don't are called @:{special
#    forms}. They are used for special jobs, like defining a function, and
#    there are not many of them. In the next few chapters, you will be
#    introduced to several of the more important special forms.
   La segunda complicación ocurre debido a que algunas funciones son inusuales y
   no funcionan de la manera habitual. Estas se llaman @:{formas especiales}
   @%i(special forms). Se utilizan para trabajos especiales, como definir una
   función, y no hay muchas de ellas. En los siguientes capítulos, se
   presentaran varias de las formas especiales más importantes.

#    The third and final complication is this: if the function that the Lisp
#    interpreter is looking at is not a special form, and if it is part of a
#    list, the Lisp interpreter looks to see whether the list has a list inside
#    of it. If there is an inner list, the Lisp interpreter first figures out
#    what it should do with the inside list, and then it works on the outside
#    list. If there is yet another list embedded inside the inner list, it
#    works on that one first, and so on. It always works on the innermost list
#    first. The interpreter works on the innermost list first, to evaluate the
#    result of that list. The result may be used by the enclosing expression.
   La tercera y ultima complicación es la siguiente: si la función que el
   intérprete Lisp está examinando no es una forma especial, y si es parte de
   una lista, el intérprete Lisp mira si la lista tiene una lista dentro de
   ella. Si existe una lista interna, el intérprete Lisp primero determina lo qué
   debe hacer con la lista interna, y luego trabaja en la lista externa. Si
   hay otra lista incrustada dentro de la lista interna, trabaja en esta
   primero, y así sucesivamente. Siempre se trabaja en la lista mas interna primero. El
   interprete trabaja primero en la lista más interana, para evaluar el
   resultado de esa lista. El resultado puede ser usado por la expresión
   entre paréntesis.

#    Otherwise, the interpreter works left to right, from one expression to the
#    next.
   Por lo demas, el intérprete trabaja de izquierda a derecha, de una expresión
   a la siguiente.

# *** Byte Compiling
*** Codigo Compilado

#     One other aspect of interpreting: the Lisp interpreter is able to
#     interpret two kinds of entity: humanly readable code, on which we will
#     focus exclusively, and specially processed code, called @:{byte compiled}
#     code, which is not humanly readable. Byte compiled code runs faster than
#     humanly readable code.
    Otro aspecto de la interpretación: el intérprete Lisp es capaz de
    interpretar dos tipos de entidades: código humanamente legible, en el que
    nos centraremos exclusivamente, y código especialmente procesado, llamado
    @:{compilado}, que no es humanamente legible. El código compilado se
    ejecuta más rápido que el código legible humanamente.

#     You can transform humanly readable code into byte compiled code by
#     running one of the compile commands such as @c{byte-compile-file}. Byte
#     compiled code is usually stored in a file that ends with a @f{.elc}
#     extension rather than a @f{.el} extension. You will see both kinds of
#     file in the @f{emacs/lisp} directory; the files to read are those with
#     @f{.el} extensions.
    Tu puedes transformar código legible por humanos en código compilado
    ejecutando uno de los comandos de compilación como @c{byte-compile-file}.
    El código compilado se almacena normalmente en un fichero que finaliza
    con una extensión @f{.elc} en lugar de una extensión @f{.el}. Verás ambos
    tipos de ficheros en el directorio @f{emacs/lisp}; los ficheros para leer
    son aquellos con la extensión @f{.el}.

#     As a practical matter, for most things you might do to customize or
#     extend Emacs, you do not need to byte compile; and I will not discuss the
#     topic here. See Section @l{elisp.html#Byte Compilation<>Byte
#     Compilation} in @e{The GNU Emacs Lisp Reference Manual}, for a full
#     description of byte compilation.
    Como una cuestión práctica, para hacer la mayoría de las cosas como
    personalizar o extender Emacs, no necesitas compilar codigo; y no
    comentare el asunto aquí. Consulta la Seccion @l{elisp.html#Byte
    Compilation<>Código Compilado} en @e(El Manual de Referencia de GNU
    Emacs Lisp), para una descripción completa de la compilacion de código.

# ** Evaluation
** Evaluación

#    When the Lisp interpreter works on an expression, the term for the
#    activity is called @:{evaluation}. We say that the interpreter ‘evaluates
#    the expression’. I've used this term several times before. The word
#    comes from its use in everyday language, ‘to ascertain the value or amount
#    of; to appraise’, according to @q{Webster's New Collegiate Dictionary}.
   Cuando el intérprete Lisp trabaja en una expresión, el término para la
   esa actividad se llama @:{evaluación}. Decimos que el intérprete ‘evalúa la
   expresión’. He usado este término varias veces antes. La palabra proviene
   de su uso en el lenguaje cotidiano, ‘para determinar el valor o la cantidad de;
   para evaluar’ segun el @e{Webster's New Collegiate Dictionary}.

#    After evaluating an expression, the Lisp interpreter will most likely
#    @:{return} the value that the computer produces by carrying out the
#    instructions it found in the function definition, or perhaps it will give
#    up on that function and produce an error message.  (The interpreter may
#    also find itself tossed, so to speak, to a different function or it may
#    attempt to repeat continually what it is doing for ever and ever in what
#    is called an ‘infinite loop’. These actions are less common; and we can
#    ignore them.)  Most frequently, the interpreter returns a value.
   Después de evaluar una expresión, es muy probable que el intérprete Lisp
   @:{devuelva} el valor que el ordenador produce al ejecutar las instrucciones
   que encuentra en la definición de la función, o quizás se de por vencido con
   en esa función y produzca un mensaje de error. (El intérprete también puede
   quedarse colgado, por así decirlo, a una función diferente o puede intentar
   repetir continuamente lo que está haciendo por siempre en lo que se llama un
   ‘bucle infinito’. Estas acciones son menos comunes; y podemos
   ignorarlas). Con mas frecuencia, el intérprete devuelve un valor.

#    At the same time the interpreter returns a value, it may do something else
#    as well, such as move a cursor or copy a file; this other kind of action
#    is called a @:{side effect}. Actions that we humans think are important,
#    such as printing results, are often “side effects” to the Lisp
#    interpreter. The jargon can sound peculiar, but it turns out that it is
#    fairly easy to learn to use side effects.
   Al mismo tiempo que el intérprete devuelve un valor, también puede realizar
   cualquier otra cosa, como mover un cursor o copiar un fichero; este otro tipo
   de acción se denomina @:{efecto secundario}. Acciones que los humanos
   pensamos que son importantes, como imprimir resultados, con frecuencia son,
   “efectos secundarios” para el intérprete Lisp. La jerga puede sonar peculiar,
   pero resulta que es bastante fácil aprender a utilizar los efectos
   secundarios.

#    In summary, evaluating a symbolic expression most commonly causes the Lisp
#    interpreter to return a value and perhaps carry out a side effect; or else
#    produce an error.
   En resumen, la evaluacion de una expresión simbólica normalmente causa que el
   intérprete devuelva un valor y tal vez lleve a cabo un efecto secundario; o
   al menos produca un error.

# *** Evaluating Inner Lists
*** Evaluación de listas internas

#     If evaluation applies to a list that is inside another list, the outer
#     list may use the value returned by the first evaluation as information
#     when the outer list is evaluated. This explains why inner expressions
#     are evaluated first: the values they return are used by the outer
#     expressions.
    Si la evaluación se aplica a una lista que está dentro de otra lista, la
    lista externa puede usar el valor devuelto por la primer evaluación como
    información cuando se evalua la lista externa. Esto explica por qué las
    expresiones internas se evaluan primero: los valores devueltos son
    usados por las expresiones externas.

#     We can investigate this process by evaluating another addition example.
#     Place your cursor after the following expression and type @k{C-x C-e}:
    Podemos investigar este proceso evaluando otro ejemplo de sumas. Coloca tu
    cursor después de la siguiente expresión y presiona @k{C-x C-e}:

#     ..src > elisp
#       (+ 2 (+ 3 3))
#     < src..
    ..src > elisp
      (+ 2 (+ 3 3))
    < src..

#     The number 8 will appear in the echo area.
    El número 8 aparecerá en el área de eco.

#     What happens is that the Lisp interpreter first evaluates the inner
#     expression, @c{(+ 3 3)}, for which the value 6 is returned; then it
#     evaluates the outer expression as if it were written @c{(+ 2 6)}, which
#     returns the value 8. Since there are no more enclosing expressions to
#     evaluate, the interpreter prints that value in the echo area.
    Lo que ocurre es que el intérprete Lisp primero evalúa la expresión
    interna, @c{(+ 3 3)}, para lo cual se devuelve el valor 6; luego
    evalúa la expresión externa como si fuera escrita @c{(+ 2 6)}, que
    devuelve el valor 8. Puesto que no hay más expresiones adjuntas a
    evaluar el intérprete imprime este valor en el área de eco.

#     Now it is easy to understand the name of the command invoked by the
#     keystrokes @k{C-x C-e}: the name is @c{eval-last-sexp}. The letters
#     @c{sexp} are an abbreviation for ‘symbolic expression’, and @c{eval} is
#     an abbreviation for ‘evaluate’. The command means ‘evaluate last
#     symbolic expression’.
    Ahora es fácil comprender el nombre del comando invocado por el atajo @k{C-x
    C-e}: el nombre es @c{eval-last-sexp}. Las letras @c{sexp} son una
    abreviatura de ‘expresión simbólica’ @%i(symbolic expression), y @c{eval} es
    una abreviatura de ‘evaluar’ @%i(evaluate). El comando significa ‘evaluar
    la última expresión simbólica’.

#     As an experiment, you can try evaluating the expression by putting the
#     cursor at the beginning of the next line immediately following the
#     expression, or inside the expression.
    Como un experimento, puedes intentar evaluar la expresión poniendo el
    cursor al principio de la siguiente línea inmediatamente después de la
    expresión, o dentro de la expresión.

#     Here is another copy of the expression:
    Aquí hay otra copia de la expresión:

#     ..src > elisp
#       (+ 2 (+ 3 3))
#     < src..
    ..src > elisp
      (+ 2 (+ 3 3))
    < src..

#     If you place the cursor at the beginning of the blank line that
#     immediately follows the expression and type @k{C-x C-e}, you will still
#     get the value 8 printed in the echo area. Now try putting the cursor
#     inside the expression. If you put it right after the next to last
#     parenthesis (so it appears to sit on top of the last parenthesis), you
#     will get a 6 printed in the echo area!  This is because the command
#     evaluates the expression @c{(+ 3 3)}.
    Si colocas el cursor al principio de la línea en blanco que sigue
    inmediatamente a la expresión y presionas @k{C-x C-e}, aún obtendrás el
    valor 8 impreso en el área eco. Ahora coloca el cursor dentro de la
    expresión. Si lo pones justo después del penúltimo paréntesis (de modo que
    parezca estar sobre el último paréntesis), ¡obtendrás un 6 impreso en el área
    de eco! Esto se debe a que el comando evalúa la expresión @c{(+ 3 3)}.

#     Now put the cursor immediately after a number. Type @k{C-x C-e} and you
#     will get the number itself. In Lisp, if you evaluate a number, you get
#     the number itself––this is how numbers differ from symbols. If you
#     evaluate a list starting with a symbol like @c{+}, you will get a value
#     returned that is the result of the computer carrying out the instructions
#     in the function definition attached to that name. If a symbol by itself
#     is evaluated, something different happens, as we will see in the next
#     section.
    Ahora coloca el cursor inmediatamente después de un número. Presiona @k{C-x
    C-e} y obtendras el número en sí. En Lisp, si evalúas un número, obtienes el
    número en sí––así es cómo los números difieren de los símbolos. Si evalúas
    una lista que inicia con un símbolo como @c{+}, obtendras un valor devuelto
    que es el resultado del ordenador tras ejecutar las instrucciones que
    aparecen en la definición de la función ligada a ese nombre. Si se evalua un
    símbolo por sí mismo, sucede algo diferente, como veremos en la siguiente
    sección.

# ** Variables
** Variables

#    In Emacs Lisp, a symbol can have a value attached to it just as it can
#    have a function definition attached to it. The two are different. The
#    function definition is a set of instructions that a computer will obey. A
#    value, on the other hand, is something, such as number or a name, that can
#    vary (which is why such a symbol is called a variable). The value of a
#    symbol can be any expression in Lisp, such as a symbol, number, list, or
#    string. A symbol that has a value is often called a @:{variable}.
   En Emacs Lisp, un símbolo puede estar ligado a un valor como a una definición
   de función. Los dos son diferentes. La definición de función es un conjunto
   de instrucciones que el ordenador ejecuta. Un valor, por otro lado, es algo,
   como un número o un nombre, que puede variar (razon por la cual tal símbolo
   se llama variable). El valor de un símbolo puede ser cualquier expresión de
   Lisp, por ejemplo un símbolo, un número, una lista, o una cadena. Un símbolo
   que tiene un valor con frecuencia se llama @:{variable}.

#    A symbol can have both a function definition and a value attached to it at
#    the same time. Or it can have just one or the other. The two are
#    separate. This is somewhat similar to the way the name Cambridge can
#    refer to the city in Massachusetts and have some information attached to
#    the name as well, such as “great programming center”.
   Un símbolo puede ser tanto una definición de función como un valor asociado a el
   al mismo tiempo. O puede tener uno u otro. Los dos son independientes.
   Esto es algo similar a la forma en que el nombre Cambridge puede referirse a
   la ciudad en Massachusetts y tener alguna información ligada al nombre, por
   ejemplo, como “gran centro de programación”.

#    Another way to think about this is to imagine a symbol as being a chest of
#    drawers. The function definition is put in one drawer, the value in
#    another, and so on. What is put in the drawer holding the value can be
#    changed without affecting the contents of the drawer holding the function
#    definition, and vice-verse.
   Otra manera de pensar en esto es imaginar un símbolo como un mueble con
   cajones. La definición de función se coloca en un cajón, el valor en otro,
   etcetera. Lo que se pone en el cajón que contiene el valor
   se puede cambiar sin afectar el contenido del cajón que almacena la
   definición de función, y viceversa.

#    The variable @c{fill-column} illustrates a symbol with a value attached to
#    it: in every GNU Emacs buffer, this symbol is set to some value, usually
#    72 or 70, but sometimes to some other value. To find the value of this
#    symbol, evaluate it by itself. If you are reading this in Info inside of
#    GNU Emacs, you can do this by putting the cursor after the symbol and
#    typing @k{C-x C-e}:
   La variable @c{fill-column} ilustra un símbolo con un valor adjunto: en
   cada buffer de GNU Emacs, este símbolo se establece en algún valor,
   normalmente 72 o 70, pero algunas veces en algún otro valor. Para encontrar
   el valor de este símbolo, evalúalo por sí mismo. Si estás leyendo esto
   dentro de GNU Emacs, puedes hacerlo poniendo el cursor después del
   símbolo y pulsando @k{C-x C-e}:

#    ..src > elisp
#      fill-column
#    < src..
   ..src > elisp
     fill-column
   < src..

#    After I typed @k{C-x C-e}, Emacs printed the number 72 in my echo area.
#    This is the value for which @c{fill-column} is set for me as I write this.
#    It may be different for you in your Info buffer. Notice that the value
#    returned as a variable is printed in exactly the same way as the value
#    returned by a function carrying out its instructions. From the point of
#    view of the Lisp interpreter, a value returned is a value returned. What
#    kind of expression it came from ceases to matter once the value is known.
   Después de presionar @k{C-x C-e}, Emacs imprimió el número 72 en mi área de
   eco. Este es el valor que he establecido para @c{fill-column} mientras
   escribo esto. Puede ser diferente en tu búfer. Observa que el valor devuelto
   como una variable se imprime exactamente de la misma forma que el valor
   devuelto por una función tras ejecutar sus instrucciones. Desde el punto de
   vista del intérprete Lisp, un valor devuelto es un valor devuelto. La clase
   de expresion de la que proviene deja de importar una vez se conoce el
   valor.

#    A symbol can have any value attached to it or, to use the jargon, we can
#    @:{bind} the variable to a value: to a number, such as 72; to a string,
#    @c{"such as this"}; to a list, such as @c{(spruce pine oak)}; we can even
#    bind a variable to a function definition.
   Un símbolo puede tener cualquier valor ligado a él o, siendo tecnicos, se
   puede @:{enlazar} la variable a un valor: a un número, por ejemplo 72; a una
   cadena, @c{"como esta"}; a una lista, como @c{(abeto pino roble)}; podemos
   incluso asociar una variable a una definición de función.

#    A symbol can be bound to a value in several ways. See Section @l{#Setting
#    the Value of a Variable}, for information about one way to do this.
   Un símbolo puede vincularse a un valor de varias maneras. Consulta la Sección
   @l{#Establecer el valor de una variable}, para obtener información sobre
   como hacerlo.

# *** Error Message for a Symbol Without a Function
*** Mensaje de error de un símbolo sin una función

#     When we evaluated @c{fill-column} to find its value as a variable, we did
#     not place parentheses around the word. This is because we did not intend
#     to use it as a function name.
    Cuando evaluamos @c{fill-column} para encontrar su valor como una
    variable, no pusimos paréntesis alrededor de la palabra. Esto se debe a
    que no pretendiamos usarla como nombre de función.

#     If @c{fill-column} were the first or only element of a list, the Lisp
#     interpreter would attempt to find the function definition attached to it.
#     But @c{fill-column} has no function definition. Try evaluating this:
    Si @c{fill-column} fuese el primer o único elemento de una lista, el
    intérprete Lisp intentaría encontrar la definición de función adjunta.
    Pero @c{fill-column} no tiene una definición de función. Intenta evaluar
    esto:

#     ..src > elisp
#       (fill-column)
#     < src..
    ..src > elisp
      (fill-column)
    < src..

#     You will create a @f{*Backtrace*} buffer that says:
    Se creará un buffer @f{*Backtrace*} que dice:

#     ..example >
#       ---------- Buffer: *Backtrace* ----------
#       Debugger entered--Lisp error: (void-function fill-column)
#         (fill-column)
#         eval((fill-column))
#         eval-last-sexp-1(nil)
#         eval-last-sexp(nil)
#         call-interactively(eval-last-sexp)
#       ---------- Buffer: *Backtrace* ----------
#     < example..
    ..example >
      ---------- Buffer: *Backtrace* ----------
      Debugger entered--Lisp error: (void-function fill-column)
        (fill-column)
        eval((fill-column))
        eval-last-sexp-1(nil)
        eval-last-sexp(nil)
        call-interactively(eval-last-sexp)
      ---------- Buffer: *Backtrace* ----------
    < example..

#     (Remember, to quit the debugger and make the debugger window go away,
#     type @k{q} in the @f{*Backtrace*} buffer.)
    (Recuerda, para salir del depurador y hacer que la ventana del depurador
    desaparezca, presiona @k{q} en el buffer @f{*Backtrace*}.)

# *** Error Message for a Symbol Without a Value
*** Mensaje de error de un símbolo sin un valor

#     If you attempt to evaluate a symbol that does not have a value bound to
#     it, you will receive an error message. You can see this by experimenting
#     with our 2 plus 2 addition. In the following expression, put your cursor
#     right after the @c{+}, before the first number 2, type @k{C-x C-e}:
    Si intentas evaluar un símbolo que no tiene un valor asociado, recibirás un
    mensaje de error. Esto se puede ver experimentando con nuestra suma 2
    más 2. En la siguiente expresión, coloca el cursor justo después del
    @c{+}, antes del primer número 2, presiona @k{C-x C-e}:

#     ..src > elisp
#       (+ 2 2)
#     < src..
    ..src > elisp
      (+ 2 2)
    < src..

#     In GNU Emacs 22, you will create a @f{*Backtrace*} buffer that says:
    En GNU Emacs 22, se creará un buffer @f{*Backtrace*} que dice:

#     ..example >
#       ---------- Buffer: *Backtrace* ----------
#       Debugger entered--Lisp error: (void-variable +)
#         eval(+ nil)
#         elisp--eval-last-sexp(nil)
#         eval-last-sexp(nil)
#         funcall-interactively(eval-last-sexp nil)
#         call-interactively(eval-last-sexp nil nil)
#         command-execute(eval-last-sexp)
#       ---------- Buffer: *Backtrace* ----------
#     < example..
    ..example >
      ---------- Buffer: *Backtrace* ----------
      Debugger entered--Lisp error: (void-variable +)
        eval(+ nil)
        elisp--eval-last-sexp(nil)
        eval-last-sexp(nil)
        funcall-interactively(eval-last-sexp nil)
        call-interactively(eval-last-sexp nil nil)
        command-execute(eval-last-sexp)
      ---------- Buffer: *Backtrace* ----------
    < example..

#     (Again, you can quit the debugger by typing @k{q} in the @f{*Backtrace*}
#     buffer.)
    (De nuevo, puedes salir del depurador pulsando @k{q} en el búfer
    @f{*Backtrace*}.)

#     This backtrace is different from the very first error message we saw,
#     which said, @'c{Debugger entered--Lisp error: (void-function this)}. In
#     this case, the function does not have a value as a variable; while in the
#     other error message, the function (the word ‘this’) did not have a
#     definition.
    Esta traza inversa es diferente del primer mensaje de error que vimos,
    que decia, @'c{Debugger entered--Lisp error: (void-function esto)}. En
    este caso, la función no tiene una valor como variable; mientras en
    el otro mensaje de error, la función (la palabra ‘esto’) no tenia una
    definición.

#     In this experiment with the @c{+}, what we did was cause the Lisp
#     interpreter to evaluate the @c{+} and look for the value of the variable
#     instead of the function definition. We did this by placing the cursor
#     right after the symbol rather than after the parenthesis of the enclosing
#     list as we did before. As a consequence, the Lisp interpreter evaluated
#     the preceding s-expression, which in this case was @c{+} by itself.
    En este experimento con el @c{+}, lo que hicimos fué hacer que el
    intérprete Lisp evalúe el @c{+} y busque el valor de la variable en lugar
    de la definición de la función. Hicimos esto colocando el cursor justo
    después del símbolo en lugar de ponerlo al final de los parentesis que
    cierran la lista como hicimos antes. Como consecuencia, el intérprete
    Lisp evaluó la expresión-s precedente, que en este caso era el @c{+} en sí.

#     Since @c{+} does not have a value bound to it, just the function
#     definition, the error message reported that the symbol's value as a
#     variable was void.
    Ya que @c{+} no tiene un valor asociado, solo la definición de función,
    el mensaje de error informaba que el valor del símbolo como una variable
    esta vacío.

# ** Arguments
** Argumentos

#    To see how information is passed to functions, let's look again at our old
#    standby, the addition of two plus two. In Lisp, this is written as
#    follows:
   Para ver cómo se pasa la información a las funciones, veamos de nuevo
   nuestro viejo recurso, la suma de dos más dos. En Lisp, esto se escribe
   de la siguiente manera:

#    ..src > elisp
#      (+ 2 2)
#    < src..
   ..src > elisp
     (+ 2 2)
   < src..

#    If you evaluate this expression, the number 4 will appear in your echo
#    area. What the Lisp interpreter does is add the numbers that follow the
#    @c{+}.
   Si evalúas esta expresión, el número 4 aparecerá en el área de eco. Lo que
   el intérprete de Lisp hace es sumar los números despues del @c{+}.

#    The numbers added by @c{+} are called the @:{arguments} of the function
#    @c{+}. These numbers are the information that is given to or @:{passed}
#    to the function.
   Los números sumados por @c{+} se llaman @:{argumentos} de la función
   @c{+}. Estos números son la información que se da o se @:{pasa} a la función.

#    The word ‘argument’ comes from the way it is used in mathematics and does
#    not refer to a disputation between two people; instead it refers to the
#    information presented to the function, in this case, to the @c{+}. In
#    Lisp, the arguments to a function are the atoms or lists that follow the
#    function. The values returned by the evaluation of these atoms or lists
#    are passed to the function. Different functions require different numbers
#    of arguments; some functions require none at all.@n{2}
   La palabra ‘argumento’ proviene de la forma en que se usa en
   matemáticas y no se refiere a una disputa entre dos personas, En su lugar,
   se refiere a la información entregada a la función, en este caso, al
   @c{+}. En Lisp, los argumentos de una función son los átomos o listas que
   siguen a la función. Los valores devueltos por la evaluación de estos
   átomos o listas se transfieren a la función. Funciones diferentes requieren
   diferentes números de argumentos; algunas funciones no requieren ninguno
   en absoluto.@n{2}

# *** Arguments' Data Types
*** Tipos de datos de los argumentos

#     The type of data that should be passed to a function depends on what kind
#     of information it uses. The arguments to a function such as @c{+} must
#     have values that are numbers, since @c{+} adds numbers. Other functions
#     use different kinds of data for their arguments.
    El tipo de datos que deben pasarse a una función dependen del tipo de
    información que utilice. Los argumentos de una función como @c{+} deben
    tener valores númericos, ya que @c{+} suma números. Otras funciones
    utilizan diferentes tipos de datos para sus argumentos.

#     For example, the @c{concat} function links together or unites two or more
#     strings of text to produce a string. The arguments are strings.
#     Concatenating the two character strings @c{abc}, @c{def} produces the
#     single string @c{abcdef}. This can be seen by evaluating the following:
    Por ejemplo, la función @c{concat} concatena o une dos o más cadenas de
    texto para producir una cadena. Los argumentos son cadenas. Concatenar
    las cadenas de caracteres @c{abc}, @c{def} produce una cadena @c{abcdef}.
    Esto se puede ver evaluando lo siguiente:

#     ..src > elisp
#       (concat "abc" "def")
#     < src..
    ..src > elisp
      (concat "abc" "def")
    < src..

#     The value produced by evaluating this expression is @c{"abcdef"}.
    El valor producido al evaluar esta expresión es @c{"abcdef"}.

#     A function such as @c{substring} uses both a string and numbers as
#     arguments. The function returns a part of the string, a substring of the
#     first argument. This function takes three arguments. Its first argument
#     is the string of characters, the second and third arguments are numbers
#     that indicate the beginning and end of the substring. The numbers are a
#     count of the number of characters (including spaces and punctuation) from
#     the beginning of the string.
    Una función como @c{substring} utiliza tanto una cadena como numeros como
    argumentos. La función devuelve una parte de la cadena, una subcadena del
    primer argumento. Esta función toma tres argumentos. Su primer argumento
    es la cadena de caracteres, el segundo y tercer argumento son números que
    indican el principio y el fin de la subcadena. Los números son un recuento
    del número de caracteres (incluyendo espacios y si signos de puntuacion) desde el
    principio de la cadena.

#     For example, if you evaluate the following:
    Por ejemplo, si evalúas lo siguiente:

#     ..src > elisp
#       (substring "The quick brown fox jumped." 16 19)
#     < src..
    ..src > elisp
      (substring "El rápido zorro marrón saltó." 10 15)
    < src..

#     you will see @c{"fox"} appear in the echo area. The arguments are the
#     string and the two numbers.
    Veras aparecer @c{"zorro"} en el área de eco. Los argumentos son la cadena y
    los dos números.

#     Note that the string passed to @c{substring} is a single atom even though
#     it is made up of several words separated by spaces. Lisp counts
#     everything between the two quotation marks as part of the string,
#     including the spaces. You can think of the @c{substring} function as a
#     kind of ‘atom smasher’ since it takes an otherwise indivisible atom and
#     extracts a part. However, @c{substring} is only able to extract a
#     substring from an argument that is a string, not from another type of
#     atom such as a number or symbol.
    Ten en cuenta que la cadena pasada a @c{substring} es un unico átomo a
    pesar de estar compuesto de varias palabras separadas por espacios. Lisp
    considera todo entre las dos comillas como parte de la cadena, incluyendo
    los espacios. Puedes pensar en la función @c{substring} como una especie
    de ‘acelerador de particulas’ ya que toma un átomo de otro modo indivisible
    y extrae una parte. Sin embargo, @c{substring} solo es capaz de extraer una
    subcadena de un argumento que es una cadena, no de otro tipo de átomo por
    ejemplo un número o símbolo.

# *** An Argument as the Value of a Variable or List
*** Un argumento como el valor de una variable o lista

#     An argument can be a symbol that returns a value when it is evaluated.
#     For example, when the symbol @c{fill-column} by itself is evaluated, it
#     returns a number. This number can be used in an addition.
    Un argumento puede ser un símbolo que devuelve un valor cuando se evalua.
    Por ejemplo, evaluar el símbolo @c{fill-column} en si mismo, devuelve un
    número. Este número se puede utilizar en una suma.

#     Position the cursor after the following expression and type @k{C-x C-e}:
    Coloca el cursor después de la siguiente expresión y presiona @k{C-x C-e}:

#     ..src > elisp
#       (+ 2 fill-column)
#     < src..
    ..src > elisp
      (+ 2 fill-column)
    < src..

#     The value will be a number two more than what you get by evaluating
#     @c{fill-column} alone. For me, this is 74, because my value of
#     @c{fill-column} is 72.
    El valor será dos mas el número que se obtiene evaluando @c{fill-column}.
    En mí caso, es 74, porque mi valor de @c{fill-column} es 72.

#     As we have just seen, an argument can be a symbol that returns a value
#     when evaluated. In addition, an argument can be a list that returns a
#     value when it is evaluated. For example, in the following expression,
#     the arguments to the function @c{concat} are the strings @c{"The "} and
#     @c{" red foxes."} and the list @c{(number-to-string (+ 2 fill-column))}.
    Como acabamos de ver, un argumento puede ser un símbolo que devuelve un valor
    cuando se evalúa. Además, un argumento puede ser una lista que devuelve
    un valor cuando se evalúa. Por ejemplo, en la siguiente expresión, los
    argumentos de la función @c{concat} son las cadenas @c{"Los "} y
    @c{" zorros rojos."} y la lista @c{(number-to-string (+ 2 fill-column))}.

#     ..src > elisp
#       (concat "The " (number-to-string (+ 2 fill-column)) " red foxes.")
#     < src..
    ..src > elisp
      (concat "Los " (number-to-string (+ 2 fill-column)) " zorros rojos.")
    < src..

#     If you evaluate this expression––and if, as with my Emacs,
#     @c{fill-column} evaluates to 72––@c{"The 74 red foxes."} will appear in
#     the echo area.  (Note that you must put spaces after the word @'{The} and
#     before the word @'{red} so they will appear in the final string. The
#     function @c{number-to-string} converts the integer that the addition
#     function returns to a string.  @c{number-to-string} is also known as
#     @c{int-to-string}.)
    Si evaluas esta expresión––y si, como con mi Emacs, @c{fill-column} se
    evalúa a 72––aparecerá @c{"Los 74 zorros rojos."} en el área de eco.
    (Ten en cuenta que debes poner espacios después de la palabra @'{Los} y
    antes de la palabra @'{zorros} para que aparezcan en la cadena final. La
    función @c{number-to-string} convierte el entero que devuelve la función
    suma a una cadena. @c{number-to-string} también se conoce como
    @c{int-to-string}.)

# *** Variable Number of Arguments
*** Número de argumentos variable

#     Some functions, such as @c{concat}, @c{+} or @c{*}, take any number of
#     arguments.  (The @c{*} is the symbol for multiplication.)  This can be
#     seen by evaluating each of the following expressions in the usual way.
    Algunas funciones, como @c{concat}, @c{+}, o @c{*}, toman cualquier
    número de argumentos. (@c{*} es el símbolo para la multiplicacion.)
    Esto se puede ver evaluando cada una de las siguientes expresiones de la
    forma habitual.

#     In the first set, the functions have no arguments:
    En el primer conjunto, las funciones no tienen argumentos:

#     ..srci > elisp
#       > (+)
#       0
#       > (*)
#       1
#     < srci..
    ..srci > elisp
      > (+)
      0
      > (*)
      1
    < srci..

#     In this set, the functions have one argument each:
    En este conjunto, las funciones tienen un argumento cada una:

#     ..srci > elisp
#       > (+ 3)
#       3
#       > (* 3)
#       3
#     < srci..
    ..srci > elisp
      > (+ 3)
      3
      > (* 3)
      3
    < srci..

#     In this set, the functions have three arguments each:
    En este conjunto, las funciones tienen tres argumentos cada una:

#     ..srci > elisp
#       > (+ 3 4 5)
#       12
#       > (* 3 4 5)
#       60
#     < srci..
    ..srci > elisp
      > (+ 3 4 5)
      12
      > (* 3 4 5)
      60
    < srci..

# *** Using the Wrong Type Object as an Argument
*** Usando el tipo incorrecto de objeto como argumento

#     When a function is passed an argument of the wrong type, the Lisp
#     interpreter produces an error message. For example, the @c{+} function
#     expects the values of its arguments to be numbers. As an experiment we
#     can pass it the quoted symbol @c{hello} instead of a number. Position
#     the cursor after the following expression and type @k{C-x C-e}:
    Cuando a una función se le pasa un argumento del tipo incorrecto, el
    interpréte Lisp produce un mensaje de error. Por ejemplo, la función
    @c{+} espera que los valores de sus argumentos sean números. Como un
    experimento podemos pasar el símbolo citado @c{hola} en lugar de un
    número. Coloca el cursor después de la siguiente expresión y presiona
    @k{C-x C-e}:

#     ..src > elisp
#       (+ 2 'hello)
#     < src..
    ..src > elisp
      (+ 2 'hola)
    < src..

#     When you do this you will generate an error message. What has happened
#     is that @c{+} has tried to add the 2 to the value returned by @c{'hello},
#     but the value returned by @c{'hello} is the symbol @c{hello}, not a
#     number. Only numbers can be added. So @c{+} could not carry out its
#     addition.
    Al hacer esto se generará un mensaje de error. Lo qué ha ocurrido es que
    @c{+} ha intentado sumar el 2 al valor devuelto por @c{'hola}, pero el
    valor devuelto por @c{'hola} es el símbolo @c{hola}, no un número. Solo
    los números se pueden sumar. Por tanto @c{+} no pudo llevar a cabo su
    suma.

#     You will create and enter a @f{*Backtrace*} buffer that says:
    Se creará e ingresara a un búfer @f{*Backtrace*} que dice:

#     ..example >
#       ---------- Buffer: *Backtrace* ----------
#       Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p hello)
#         +(2 hello)
#         eval((+ 2 (quote hello)) nil)
#         eval-last-sexp-1(nil)
#         eval-last-sexp(nil)
#         call-interactively(eval-last-sexp nil nil)
#         command-execute(eval-last-sexp)
#       ---------- Buffer: *Backtrace* ----------
#     < example..
    ..example >
      ---------- Buffer: *Backtrace* ----------
      Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p hola)
        +(2 hola)
        eval((+ 2 (quote hola)) nil)
        eval-last-sexp-1(nil)
        eval-last-sexp(nil)
        call-interactively(eval-last-sexp nil nil)
        command-execute(eval-last-sexp)
      ---------- Buffer: *Backtrace* ----------
    < example..

#     As usual, the error message tries to be helpful and makes sense after you
#     learn how to read it.@n{3}
    Como de costumbre, el mensaje de error intenta ser útil y tiene sentido
    después de aprender a leerlo.@n{3}

#     The first part of the error message is straightforward; it says @'{wrong
#     type argument}. Next comes the mysterious jargon word
#     @'{number-or-marker-p}. This word is trying to tell you what kind of
#     argument the @c{+} expected.
    La primer parte del mensaje de error es sencilla; dice @'{wrong type
    argument} @%i(tipo de argumento incorrecto). A continuación viene la
    misteriosa jerga tecnica @'{number-or-marker-p}. Esta palabra está
    intentando decirte qué tipo de argumento espera @c{+}.

#     The symbol @c{number-or-marker-p} says that the Lisp interpreter is
#     trying to determine whether the information presented it (the value of
#     the argument) is a number or a marker (a special object representing a
#     buffer position). What it does is test to see whether the @c{+} is being
#     given numbers to add. It also tests to see whether the argument is
#     something called a marker, which is a specific feature of Emacs Lisp.
#     (In Emacs, locations in a buffer are recorded as markers. When the mark
#     is set with the @k{C-@@} or @k{C-SPC} command, its position is kept
#     as a marker. The mark can be considered a number––the number of
#     characters the location is from the beginning of the buffer.)  In Emacs
#     Lisp, @c{+} can be used to add the numeric value of marker positions as
#     numbers.
    El símbolo @c{number-or-marker-p} dice que el intérprete Lisp está
    intentando determinar si la información presentada (el valor del argumento)
    es un número o una marca (un objeto especial que representa una posición de
    buffer). Lo que hace es probar si se le estan dando numeros a sumar a
    @c{+}. También comprueba si el argumento es algo llamado marcador, que es una
    caracteristica específica de Emacs Lisp. (En Emacs, las ubicaciones en un
    búfer se registran como marcadores. Cuando se establece la marca con el
    comando @k{C-@@} o @k{C-SPC}, su posición se guarda como un marcador. La
    marca se puede consider un número––el número de caracteres es la ubicacion
    desde el principio del búfer.)  En Emacs Lisp, @c{+} se puede utilizar para
    sumar el valor numérico de los marcadores como números.

#     The @'{p} of @c{number-or-marker-p} is the embodiment of a practice
#     started in the early days of Lisp programming. The @'{p} stands for
#     ‘predicate’. In the jargon used by the early Lisp researchers, a
#     predicate refers to a function to determine whether some property is true
#     or false. So the @'{p} tells us that @c{number-or-marker-p} is the name
#     of a function that determines whether it is true or false that the
#     argument supplied is a number or a marker. Other Lisp symbols that end
#     in @'{p} include @c{zerop}, a function that tests whether its argument
#     has the value of zero, and @c{listp}, a function that tests whether its
#     argument is a list.
    La @'{p} en @c{number-or-marker-p} es la encarnación de una práctica
    iniciada en los primeros días de la programación Lisp. La @'{p} significa
    ‘predicado’. En la jerga usada por los primeros investigadores de Lisp,
    un predicado se refiere a una función para determinar si alguna propiedad
    es verdadera o falsa. Entonces la @'{p} nos dice que @c{number-or-marker-p}
    es el nombre de una función que determina si el argumento dado es un
    número o un marcador. Otros símbolos Lisp que finalizan en @'{p} incluyen
    @c{zerop}, una función que comprueba si su argumento tiene el valor de
    cero, y @c{listp}, una función que comprueba si su argumento es una
    lista.

#     Finally, the last part of the error message is the symbol @c{hello}.
#     This is the value of the argument that was passed to @c{+}. If the
#     addition had been passed the correct type of object, the value passed
#     would have been a number, such as 37, rather than a symbol like
#     @c{hello}. But then you would not have got the error message.
    Finalmente, la última parte del mensaje de error es el símbolo @c{hola}.
    Este es el valor del argumento que se paso a @c{+}. Si a la suma se le hubiera
    pasado el tipo correcto de objeto, el valor habría sido un número, como
    37, en lugar de un símbolo como @c{hola}. Pero entonces no habrías
    recibido el mensaje de error.

# *** The @c{message} Function
*** La función @c{message}

#     Like @c{+}, the @c{message} function takes a variable number of
#     arguments. It is used to send messages to the user and is so useful that
#     we will describe it here.
    Al igual que @c{+}, la función @c{message} toma un número de argumentos
    variable. Se utiliza para enviar mensajes al usuario y es tan útil que
    la describiremos aqui.

#     A message is printed in the echo area. For example, you can print a
#     message in your echo area by evaluating the following list:
    Se imprime un mensaje en el área de eco. Por ejemplo, puedes imprimir un
    mensaje en tu área de eco evaluando la siguiente lista:

#     ..src > elisp
#       (message "This message appears in the echo area!")
#     < src..
    ..src > elisp
      (message "¡Este mensaje aparece en el área de eco!")
    < src..

#     The whole string between double quotation marks is a single argument and
#     is printed @i{in toto}. (Note that in this example, the message itself
#     will appear in the echo area within double quotes; that is because you
#     see the value returned by the @c{message} function. In most uses of
#     @c{message} in programs that you write, the text will be printed in the
#     echo area as a side-effect, without the quotes. See Section @l{#An
#     Interactive @c{multiply-by-seven}} in detail, for an example of this.)
    Toda la cadena entre comillas dobles es un unico argumento y se imprime
    @i{en su totalidad}. (Obseva que en este ejemplo, el mensaje mismo aparece
    en el área de eco entre comillas dobles; esto se debe a que ves el valor
    devuelto por la función @c{message}. En la mayoría de programas que
    escribiras, el texto se imprimira en el área de eco como un efecto
    secundario de @c{message}, sin las comillas. Consulta la Sección
    @l{#@c{multiplicar-por-siete} interactivo}, para ver en detalle un ejemplo
    de esto.)

#     However, if there is a @'c{%s} in the quoted string of characters, the
#     @c{message} function does not print the @'c{%s} as such, but looks to the
#     argument that follows the string. It evaluates the second argument and
#     prints the value at the location in the string where the @'c{%s} is.
    Sin embargo, si hay un @'c{%s} en la cadena de caracteres entre comillas, la
    función @c{message} no imprime el @'c{%s} como tal, si no que mira el siguente
    argumento a continuacion de la cadena. Evalúa el segundo argumento e
    imprime el valor en la ubicación de la cadena donde está el @'c{%s}.

#     You can see this by positioning the cursor after the following expression
#     and typing @k{C-x C-e}:
    Puedes ver esto colocando el cursor después de la siguiente expresión y
    presionar @k{C-x C-e}:

#     ..src > elisp
#       (message "The name of this buffer is: %s." (buffer-name))
#     < src..
    ..src > elisp
      (message "El nombre de este búfer es: %s." (buffer-name))
    < src..

#     In Info, @c{"The name of this buffer is: *info*."} will appear in the
#     echo area. The function @c{buffer-name} returns the name of the buffer
#     as a string, which the @c{message} function inserts in place of @c{%s}.
    En Info, @c{"El nombre de este búfer es: *info*."} aparecerá en el área
    de eco. La función @c{buffer-name} devuelve el nombre del búfer como una
    cadena, que la función @c{message} inserta en lugar de @c{%s}.

#     To print a value as an integer, use @'{%d} in the same way as @'{%s}.
#     For example, to print a message in the echo area that states the value of
#     the @c{fill-column}, evaluate the following:
    Para imprimir un valor como un entero, utiliza @'{%d} de la misma forma
    que @'{%s}. Por ejemplo, para imprimir un mensaje en el área de eco que
    indique el valor de @c{fill-column}, evalúa lo siguiente:

#     ..src > elisp
#       (message "The value of fill-column is %d." fill-column)
#     < src..
    ..src > elisp
      (message "El valor de fill-column es %d." fill-column)
    < src..

#     On my system, when I evaluate this list, @c{"The value of fill-column is
#     72."} appears in my echo area@n{4}.
    En mi sistema, cuando evalúo esta lista, @c{"El valor de fill-column es
    72"} aparece en mi área de eco@n{4}.

#     If there is more than one @'{%s} in the quoted string, the value of the
#     first argument following the quoted string is printed at the location of
#     the first @'{%s} and the value of the second argument is printed at the
#     location of the second @'{%s}, and so on.
    Si hay más de un @'{%s} en la cadena entre comillas, el valor del primer
    argumento después de la cadena se imprime en la posición del
    primer @'{%s} y el valor del segundo argumento se imprime en la posición
    del segundo @'{%s}, y así sucesivamente.

#     For example, if you evaluate the following,
    Por ejemplo, si evalúas lo siguiente,

#     ..src > elisp
#       (message "There are %d %s in the office!"
#                (- fill-column 14) "pink elephants")
#     < src..
    ..src > elisp
      (message "¡Hay %d %s en la oficina!"
               (- fill-column 14) "elefantes rosas")
    < src..

#     a rather whimsical message will appear in your echo area. On my system
#     it says, @c{"There are 58 pink elephants in the office!"}.
    aparecerán un mensaje un poco caprichoso en el área de eco. En mi sistema
    dice @c{"¡Hay 58 elefantes rosas en la oficina!"}

#     The expression @c{(- fill-column 14)} is evaluated and the resulting
#     number is inserted in place of the @'c{%d}; and the string in double
#     quotes, @c{"pink elephants"}, is treated as a single argument and
#     inserted in place of the @'c{%s}.  (That is to say, a string between
#     double quotes evaluates to itself, like a number.)
    Se evalúa la expresión @c{(- fill-column 14)} y el número resultante
    se inserta en lugar del @'c{%d}; y la cadena entre comillas dobles,
    @c{"elefantes rosas"}, se trata como un unico argumento y se inserta
    en lugar del @'c{%s}. (Es decir, una cadena entre comillas dobles se
    evalúa así misma, como un número.)

#     Finally, here is a somewhat complex example that not only illustrates the
#     computation of a number, but also shows how you can use an expression
#     within an expression to generate the text that is substituted for @'c{%s}:
    Por último, aquí está un ejemplo algo complejo que no solo ilustra el
    cálculo de un número, sino que también muestra como se puede usar una expresión
    dentro de una expresión para generar el texto que sustituira el @'c{%s}:

#     ..src > elisp
#       (message "He saw %d %s"
#                (- fill-column 32)
#                (concat "red "
#                        (substring
#                         "The quick brown foxes jumped." 16 21)
#                        " leaping."))
#     < src..
    ..src > elisp
      (message "Él vió %d %s"
               (- fill-column 36)
               (concat (substring
                        "Los rápidos zorros marrones saltaron." 12 18)
                       " rojos"
                       " saltando."))
    < src..

#     In this example, @c{message} has three arguments: the string, @c{"He saw
#     %d %s"}, the expression, @c{(- fill-column 32)}, and the expression
#     beginning with the function @c{concat}. The value resulting from the
#     evaluation of @c{(- fill-column 32)} is inserted in place of the @'{%d};
#     and the value returned by the expression beginning with @c{concat} is
#     inserted in place of the @'{%s}.
    En este ejemplo, @c{message} tiene tres argumentos: la cadena, @c{"Él vió
    %d %s"}, la expresión, @c{(- fill-column 32)}, y la expresion que comienza con
    la función @c{concat}. El valor resultante de la evaluación de @c{(-
    fill-column 32)} se inserta en lugar del @'{%d}; y el valor devuelto por
    la expresión que inicia con @c{concat} se inserta en lugar del @'{%s}.

#     When your @c(fill-column) is 70 and you evaluate the expression, the message
#     @c{"He saw 38 red foxes leaping."} appears in your echo area.
    Cuando @c(fill-column) es 70 y evaluas la expresión, aparecera el
    mensaje @c{"Él vió 38 zorros rojos saltando."} en tu área de eco.

# ** Setting the Value of a Variable
** Establecer el valor de una variable

#    There are several ways by which a variable can be given a value. One of
#    the ways is to use either the function @c{set} or the function @c{setq}.
#    Another way is to use @c{let} (see Section @l{#@c{let}}). (The jargon for
#    this process is to @:{bind} a variable to a value.)
   Hay varias formas de asignar un valor a una variable. Una de ellas es
   utilizar la función @c{set} o la función @c{setq}. Otra forma es utilizar
   @c{let} (Consulta la Seccion @l{#@c(let)}). (La jerga para este proceso es @:{ligar}
   @%i(bind) una variable a un valor.)

#    The following sections not only describe how @c{set} and @c{setq} work but
#    also illustrate how arguments are passed.
   Las siguientes secciones no solo describen cómo operan @c{set} y @c{setq},
   también ilustran como se pasan los argumentos.

# *** Using @c{set}
*** Usando @c{set}

#     To set the value of the symbol @c{flowers} to the list @c{'(rose violet
#     daisy buttercup)}, evaluate the following expression by positioning the
#     cursor after the expression and typing @k{C-x C-e}.
    Para establecer el valor del símbolo @c{flores} a la lista @c{'(rosa
    violeta margarita tulipan)}, evalúa la siguiente expresión colocando
    el cursor después de la expresión y presiona @k{C-x C-e}.

#     ..src > elisp
#       (set 'flowers '(rose violet daisy buttercup))
#     < src..
    ..src > elisp
      (set 'flores '(rosa violeta margarita tulipan))
    < src..

#     The list @c{(rose violet daisy buttercup)} will appear in the echo area.
#     This is what is @e{returned} by the @c{set} function. As a side effect,
#     the symbol @c{flowers} is bound to the list; that is, the symbol
#     @c{flowers}, which can be viewed as a variable, is given the list as its
#     value.  (This process, by the way, illustrates how a side effect to the
#     Lisp interpreter, setting the value, can be the primary effect that we
#     humans are interested in. This is because every Lisp function must
#     return a value if it does not get an error, but it will only have a side
#     effect if it is designed to have one.)
    La lista @c{(rosa violeta margarita tulipan)} aparecerá en el área de
    eco. Esto es la que @e{devuelve} la función @c{set}. Como efecto secundario,
    el símbolo @c{flores} esta ligado a la lista; es decir, el símbolo
    @c{flores}, puede verse como una variable, que entrega la lista como su
    valor. (Por cierto, este proceso, ilustra como un efecto secundario del
    intérprete Lisp, al establecer el valor, puede ser el principal efecto que
    nos interesa a los humanos. Esto se debe a que cada función Lisp debe
    devolver un valor si no obtiene un error, pero solo tendrá un efecto
    secundario si está diseñada para tenerlo.)

#     After evaluating the @c{set} expression, you can evaluate the symbol
#     @c{flowers} and it will return the value you just set. Here is the
#     symbol. Place your cursor after it and type @k{C-x C-e}.
    Después de evaluar la expresión @c{set}, se puede evaluar el símbolo
    @c{flores} y devolvera el valor que se acaba de establecer. Aquí está
    el símbolo. Coloca el cursor al final de este y presiona @k{C-x C-e}.

#     ..src > elisp
#       flowers
#     < src..
    ..src > elisp
      flores
    < src..

#     When you evaluate @c{flowers}, the list @c{(rose violet daisy buttercup)}
#     appears in the echo area.
    Al evalúar @c{flores}, aparece la lista @c{(rosa violeta margarita tulipan)}
    en el área de eco.

#     Incidentally, if you evaluate @c{'flowers}, the variable with a quote in
#     front of it, what you will see in the echo area is the symbol itself,
#     @c{flowers}. Here is the quoted symbol, so you can try this:
    Por cierto, si se evalúa @c{'flores}, la variable con una cita frente a
    ella, lo que verás en el área de eco es el símbolo en sí mismo, @c{flores}.
    Aquí está el símbolo citado, asi que puedes intentarlo:

#     ..src > elisp
#       'flowers
#     < src..
    ..src > elisp
      'flores
    < src..

#     Note also, that when you use @c{set}, you need to quote both arguments to
#     @c{set}, unless you want them evaluated. Since we do not want either
#     argument evaluated, neither the variable @c{flowers} nor the list
#     @c{(rose violet daisy buttercup)}, both are quoted.  (When you use
#     @c{set} without quoting its first argument, the first argument is
#     evaluated before anything else is done. If you did this and @c{flowers}
#     did not have a value already, you would get an error message that the
#     @'{Symbol's value as variable is void}; on the other hand, if @c{flowers}
#     did return a value after it was evaluated, the @c{set} would attempt to
#     set the value that was returned. There are situations where this is the
#     right thing for the function to do; but such situations are rare.)
    Ten en cuenta también, que cuando se utiliza @c{set}, es necesario citar
    ambos argumentos, a menos que quieras que sean avaluados. Como no queremos
    que se evalue ninguno de los dos argumentos, se citan tanto la variable
    @c{flores}, como la lista @c{(rosa violeta margarita tulipan)}. (Cuando se
    utiliza @c{set} sin citar su primer argumento, el primer argumento se evalúa
    antes de realizar cualquier otra cosa. Si se hace esto y @c{flores} no tenía ya
    un valor, obtendras un mensaje de error de tipo, @'{El valor de símbolo como
    variable esta vacío}; por otro lado, si @c{flores} regresa un valor después
    de ser evaluada, @c{set} intentaría establecer el valor que fue devuelto.
    Hay situaciones donde esto es justo lo que la función a de hacer, pero estas
    situaciones son poco frecuentes.)

# *** Using @c{setq}
*** Usando @c{setq}

#     As a practical matter, you almost always quote the first argument to
#     @c{set}. The combination of @c{set} and a quoted first argument is so
#     common that it has its own name: the special form @c{setq}. This special
#     form is just like @c{set} except that the first argument is quoted
#     automatically, so you don't need to type the quote mark yourself. Also,
#     as an added convenience, @c{setq} permits you to set several different
#     variables to different values, all in one expression.
    Como una cuestión práctica, casi siempre se cita el primer argumento de
    @c{set}. La combinación de @c{set} y un primer argumento citado es tan
    común que tiene su propio nombre: la forma especial @c{setq}. Esta forma
    especial es similar a @c{set} excepto que el primer argumento se citado
    automáticamente, por lo que no es necesario escribir la marca de cita.
    Ademas, como una conveniencia adicional, @c{setq} permite asignar varias
    variables diferentes a diferentes valores, todo en una sola expresión.

#     To set the value of the variable @c{carnivores} to the list @c{'(lion
#     tiger leopard)} using @c{setq}, the following expression is used:
    Para establecer el valor de la variable @c{carnívoros} a la lista
    @c{'(leon tigre leopardo)} usando @c{setq}, se utiliza la siguiente
    expresión:

#     ..src > elisp
#       (setq carnivores '(lion tiger leopard))
#     < src..
    ..src > elisp
      (setq carnivoros '(leon tigre leopardo))
    < src..

#     This is exactly the same as using @c{set} except the first argument is
#     automatically quoted by @c{setq}.  (The @'{q} in @c{setq} means
#     @c{quote}.)
    Esto es exactamente igual que usar @c{set} excepto que el primer
    argumento se cita automáticamente por @c{setq}. (La @'{q} en @c{setq}
    significa @c{quote} @%i(cita).)

#     With @c{set}, the expression would look like this:
    Con @c{set}, la expresión se vería asi:

#     ..src > elisp
#       (set 'carnivores '(lion tiger leopard))
#     < src..
    ..src > elisp
      (set 'carnivoros '(leon tigre leopardo))
    < src..

#     Also, @c{setq} can be used to assign different values to different
#     variables. The first argument is bound to the value of the second
#     argument, the third argument is bound to the value of the fourth
#     argument, and so on. For example, you could use the following to assign
#     a list of trees to the symbol @c{trees} and a list of herbivores to the
#     symbol @c{herbivores}:
    Además, @c{setq} se puede utilizar para asignar diferentes valores a
    diferentes variables. El primer argumento se une al valor del segundo
    argumento, el tercer argumento se une a al valor del cuarto argumento, y
    así sucesivamente. Por ejemplo, podría utilizar lo siguiente para asignar
    una lista de árboles al símbolo @c{arboles} y una lista de herbívoros al
    símbolo @c{herbivoros}:

#     ..src > elisp
#       (setq trees '(pine fir oak maple)
#             herbivores '(gazelle antelope zebra))
#     < src..
    ..src > elisp
      (setq arboles '(pino abeto roble arce)
            herbivoros '(gacela antilope cebra))
    < src..

#     (The expression could just as well have been on one line, but it might
#     not have fit on a page; and humans find it easier to read nicely
#     formatted lists.)
    (La expresión podría también haber estado en una unica línea, pero podría
    no caber en una página; y a los humanos les resulta más fácil leer listas
    con un formato agradable.)

#     Although I have been using the term ‘assign’, there is another way of
#     thinking about the workings of @c{set} and @c{setq}; and that is to say
#     that @c{set} and @c{setq} make the symbol @e{point} to the list. This
#     latter way of thinking is very common and in forthcoming chapters we
#     shall come upon at least one symbol that has ‘pointer’ as part of its
#     name. The name is chosen because the symbol has a value, specifically a
#     list, attached to it; or, expressed another way, the symbol is set to
#     “point” to the list.
    Aunque he estado usando el término ‘asignar’, hay otra forma de pensar
    respecto a el funcionamiento de @c{set} y @c{setq}; y consiste en decir
    que @c{set} y @c{setq} hacen que el símbolo @e{apunte} a la lista. Esta
    ultima forma de pensar es muy común y en los proximos capítulos nos
    encontraremos con al menos un símbolo que tiene ‘puntero’ como parte de
    su nombre. El nombre se elige porque el símbolo tiene un valor,
    específicamente una lista, unida a el; o, expresado de otra manera, el
    símbolo se establece como “puntero” a la lista.

# *** Counting
*** Conteo

#     Here is an example that shows how to use @c{setq} in a counter. You
#     might use this to count how many times a part of your program repeats
#     itself. First set a variable to zero; then add one to the number each
#     time the program repeats itself. To do this, you need a variable that
#     serves as a counter, and two expressions: an initial @c{setq} expression
#     that sets the counter variable to zero; and a second @c{setq} expression
#     that increments the counter each time it is evaluated.
    He aquí un ejemplo que muestra cómo utilizar @c{setq} en un contador. Es
    posible usar esto para contar cuantas veces se repite una parte de un
    programa. En primer lugar se necesita establecer una variable a cero; luego
    sumar uno al número cada vez que el programa se repita. Para hacer esto, se
    requiere una variable que sirva como contador, y dos expresiones: una
    expresión @c{setq} inicial que asigne la variable contador a cero; y una
    segunda expresión @c{setq} que incremente el contador cada vez se evalue.

#     ..src > elisp
    ..src > elisp
#       (setq counter 0)                ; Let's call this the initializer.
      (setq contador 0)                ; Llamemos a esto el inicializador.

#       (setq counter (+ counter 1))    ; This is the incrementer.
      (setq contador (+ contador 1))   ; Este es el incremento.

#       counter                         ; This is the counter.
      contador                         ; Este es el contador.
#     < src..
    < src..

#     (The text following the @'{;} are comments. See Section @l{#Change a
#     Function Definition}.)
    (El texto que sigue al @'{;} son los comentarios. Consulta la Seccion
    @l{#Cambiar una definición de función}.)

#     If you evaluate the first of these expressions, the initializer, @c{(setq
#     counter 0)}, and then evaluate the third expression, @c{counter}, the
#     number @c{0} will appear in the echo area. If you then evaluate the
#     second expression, the incrementer, @c{(setq counter (+ counter 1))}, the
#     counter will get the value 1. So if you again evaluate @c{counter}, the
#     number @c{1} will appear in the echo area. Each time you evaluate the
#     second expression, the value of the counter will be incremented.
    Si evalúas la primera de estas expresiones, el inicializador, @c{(setq
    contador 0)}, y luego evalúas la tercera expresión, @c{contador}, el
    número @c{0} aparecerá en el área de eco. Si a continuación se evalúa la
    segunda expresión, el incremento, @c{(setq contador (+ contador 1))}, el
    contador tendrá el valor 1. Así que si evalúas de nuevo @c{contador}, el
    número @c{1} aparecerá en el área de eco. Cada vez que se evalúa la segunda
    expresión, el valor del contador se incrementara.

#     When you evaluate the incrementer, @c{(setq counter (+ counter 1))}, the
#     Lisp interpreter first evaluates the innermost list; this is the
#     addition. In order to evaluate this list, it must evaluate the variable
#     @c{counter} and the number @c{1}. When it evaluates the variable
#     @c{counter}, it receives its current value. It passes this value and the
#     number @c{1} to the @c{+} which adds them together. The sum is then
#     returned as the value of the inner list and passed to the @c{setq} which
#     sets the variable @c{counter} to this new value. Thus, the value of the
#     variable, @c{counter}, is changed.
    Al evalúar el incremento, @c{(setq contador (+ contador 1))}, el intérprete
    Lisp evalúa en primer lugar la lista interna; esta es la suma. Para evaluar
    esta lista, se debe evaluar la variable @c{contador} y el número @c{1}.
    Cuando evalúa la variable @c{contador}, recibe su valor actual. Se pasa
    este valor y el número @c{1} a @c{+} que los suma. La suma se devuelve como
    el valor de la lista interior y pasa a @c{setq} que establece la variable
    @c{contador} a este nuevo valor. Por lo tanto, el valor de la variable
    @c{contador}, cambia.

# ** Summary
** Resumen

#    Learning Lisp is like climbing a hill in which the first part is the
#    steepest. You have now climbed the most difficult part; what remains
#    becomes easier as you progress onwards.
   Aprender Lisp es como subir una colina en la que la primera parte es la
   mas empinada. Ahora has subido la parte más difícil; lo que queda se
   vuelve más fácil a medida que avanzas hacia adelante.

#    In summary,
   En resumen,

#    - Lisp programs are made up of expressions, which are lists or single
#      atoms.
   - Los programas Lisp se componen de expresiones, que son listas o átomos
     individuales.

#    - Lists are made up of zero or more atoms or inner lists, separated by
#      whitespace and surrounded by parentheses. A list can be empty.
   - Las listas se componen de cero o más átomos o listas internas, separadas
     por espacios en blanco y rodeadas por paréntesis. Una lista puede estar
     vacía.

#    - Atoms are multi-character symbols, like @c{forward-paragraph}, single
#      character symbols like @c{+}, strings of characters between double
#      quotation marks, or numbers.
   - Los átomos son símbolos de varios caracteres, como @c{forward-paragraph},
     símbolos de un solo caracter como @c{+}, cadenas de caracteres entre
     comillas dobles, o números.

#    - A number evaluates to itself.
   - Un número se evalúa a sí mismo.

#    - A string between double quotes also evaluates to itself.
   - Una cadena entre comillas dobles también se evalúa a sí misma.

#    - When you evaluate a symbol by itself, its value is returned.
   - Cuando se evalúa un símbolo en si, se devuelve su valor.

#    - When you evaluate a list, the Lisp interpreter looks at the first symbol
#      in the list and then at the function definition bound to that symbol.
#      Then the instructions in the function definition are carried out.
   - Cuando se evalúa una lista, el intérprete Lisp mira el primer símbolo en
     la lista y luego la definición de función asociada a ese símbolo. A
     continuación se ejecutan las instrucciones en la definición de la función.

#    - A single quotation mark, @c{'}, tells the Lisp interpreter that it
#      should return the following expression as written, and not evaluate it
#      as it would if the quote were not there.
   - Una marca de cita, @c{'}, le indica al intérprete Lisp que devuelva la
     siguiente expresión tal como esta escrita, y no evaluarla como lo haria si
     la cita no estuviera alli.

#    - Arguments are the information passed to a function. The arguments to a
#      function are computed by evaluating the rest of the elements of the list
#      of which the function is the first element.
   - Los argumentos son la información que se pasa a una función. Los
     argumentos de una función se calculan evaluando el resto de los
     elementos de la lista de los cuales la función es el primer elemento.

#    - A function always returns a value when it is evaluated (unless it gets
#      an error); in addition, it may also carry out some action called a “side
#      effect”. In many cases, a function's primary purpose is to create a
#      side effect.
   - Una función siempre devuelve un valor cuando se evalúa (a menos que
     se produzca un error); además, también se puede llevar a cabo alguna
     acción llamada “efecto secundario”. En muchos casos, el propósito
     principal de una función es crear un efecto secundario.

# ** Exercises
** Ejercicios

#    A few simple exercises:
   Unos cuantos ejercicios simples:

#    - Generate an error message by evaluating an appropriate symbol that is
#      not within parentheses.
   - Genera un mensaje de error evaluando un símbolo apropiado que no este
     entre paréntesis.

#    - Generate an error message by evaluating an appropriate symbol that is
#      between parentheses.
   - Genera un mensaje de error evaluando un símbolo apropiado que se encuentre
     entre paréntesis.

#    - Create a counter that increments by two rather than one.
   - Crea un contador que se incrementa en dos en lugar de en uno.

#    - Write an expression that prints a message in the echo area when
#      evaluated.
   - Escribe una expresión que imprima un mensaje en el área de eco cuando se
     evalue.

# * Practicing Evaluation
* Practicando la Evaluación

#   Before learning how to write a function definition in Emacs Lisp, it is
#   useful to spend a little time evaluating various expressions that have
#   already been written. These expressions will be lists with the functions
#   as their first (and often only) element. Since some of the functions
#   associated with buffers are both simple and interesting, we will start with
#   those. In this section, we will evaluate a few of these. In another
#   section, we will study the code of several other buffer-related functions,
#   to see how they were written.
  Antes de aprender a escribir una definición de función en Emacs Lisp, es
  útil dedicar un poco de tiempo a evaluar varias expresiones que ya han sido
  escritas. Estas expresiones serán listas con funciones como su primer (y con
  frecuencia único) elemento. Dado que algunas de las funciones asociadas con
  búfers son a la vez simples e interesantes, empezaremos por ellas. En esta
  sección, vamos a evaluar algunas. En otra sección, estudiaremos el código de
  varias otras funciones relacionadas con búfers, para ver la forma cómo fueron
  escritas.

#   @i{Whenever you give an editing command} to Emacs Lisp, such as the command
#   to move the cursor or to scroll the screen, @i{you are evaluating an
#   expression,} the first element of which is a function.  @i{This is how
#   Emacs works.}
  @i{Siempre que se le da un comando de edición} a Emacs Lisp, como el
  comando para mover el cursor o para desplazarse por la pantalla, @i{se está
  evaluando una expresión}, cuyo primer elemento es una función. @i{Así es cómo
  funciona Emacs}.

#   When you type keys, you cause the Lisp interpreter to evaluate an
#   expression and that is how you get your results. Even typing plain text
#   involves evaluating an Emacs Lisp function, in this case, one that uses
#   @c{self-insert-command}, which simply inserts the character you typed. The
#   functions you evaluate by typing keystrokes are called @:{interactive}
#   functions, or @:{commands}; how you make a function interactive will be
#   illustrated in the chapter on how to write function definitions. See
#   Section @l{#Make a Function Interactive}.
  Al presionar las teclas, haces que el interprete Lisp evalue una expresion y
  asi es como obtienes resultados. Incluso escribir texto plano implica
  evalúar una función de Emacs Lisp, en este caso, se utiliza
  @c{self-insert-command}, que simplemente inserta el caracter que has escrito.
  Las funciones que se evalúan presionando atajos de teclado se llaman funciones
  @:{interactivas}, o @:{comandos}; la forma de hacer que una funcion sea
  interactiva se ilustrara en el capítulo sobre cómo escribir definiciones de
  funcion. Consulta la Seccion @l{#Crear una Función Interactiva}.

#   In addition to typing keyboard commands, we have seen a second way to
#   evaluate an expression: by positioning the cursor after a list and typing
#   @k{C-x C-e}. This is what we will do in the rest of this section. There
#   are other ways to evaluate an expression as well; these will be described
#   as we come to them.
  Además de presionar comandos de teclado, hemos visto una segunda manera de
  evaluar una expresión: colocar el cursor después de una lista y presionar
  @k{C-x C-e}. Esto es lo que haremos en el resto de esta sección. Hay otras
  maneras de evaluar una expresión; estas serán descritas a medida que llegemos a
  ellas.

#   Besides being used for practicing evaluation, the functions shown in the
#   next few sections are important in their own right. A study of these
#   functions makes clear the distinction between buffers and files, how to
#   switch to a buffer, and how to determine a location within it.
  Ademas de utilizarlas para prácticar la evaluación, las funciones que se
  muestran en las siguientes secciones son importantes por derecho propio. Un
  estudio de estas funciones deja claro la distinción entre búfers y ficheros,
  cómo cambiar a un búfer, y como determinar una ubicación dentro de el.

# ** Buffer Names
** Nombres de búfer

#    The two functions, @c{buffer-name} and @c{buffer-file-name}, show the
#    difference between a file and a buffer. When you evaluate the following
#    expression, @c{(buffer-name)}, the name of the buffer appears in the echo
#    area. When you evaluate @c{(buffer-file-name)}, the name of the file to
#    which the buffer refers appears in the echo area. Usually, the name
#    returned by @c{(buffer-name)} is the same as the name of the file to which
#    it refers, and the name returned by @c{(buffer-file-name)} is the full
#    path-name of the file.
   Las dos funciones, @c{buffer-name} y @c{buffer-file-name}, muestran la
   diferencia entre un fichero y un búfer. Cuando se evalúa la siguiente
   expresión, @c{(buffer-name)}, el nombre del buffer aparece en el area eco.
   Al evaluar @c{(buffer-file-name)}, el nombre del fichero al que hace
   referencia el búfer aparece en el área de eco. Por lo general, el nombre
   devuelto por @c{(buffer-name)} es el mismo que el nombre del fichero al
   que hace referencia, y el nombre devuelto por @c{(buffer-file-name)} es la
   ruta completa del fichero.

#    A file and a buffer are two different entities. A file is information
#    recorded permanently in the computer (unless you delete it). A buffer, on
#    the other hand, is information inside of Emacs that will vanish at the end
#    of the editing session (or when you kill the buffer). Usually, a buffer
#    contains information that you have copied from a file; we say the buffer
#    is @:{visiting} that file. This copy is what you work on and modify.
#    Changes to the buffer do not change the file, until you save the buffer.
#    When you save the buffer, the buffer is copied to the file and is thus
#    saved permanently.
   Un fichero y un búfer son dos entidades diferentes. Un fichero es la
   información grabada de manera permanente en el ordenador (a menos que se
   elimine). Un búfer, por otro lado, es información dentro de Emacs que
   desaparecerá al final de la sesión de edición (o cuando mates el búfer).
   Por lo general, un búfer contiene información que se ha copiado
   desde un fichero; decimos que el búfer está @:{visitando} ese fichero.
   Esta copia es en la que se trabaja y modifica. Los cambios en el búfer no
   modifican el fichero, hasta guardar el búfer. Al guardar el búfer, el búfer
   se copia en el fichero y por lo tanto se guarda de forma permanente.

#    If you are reading this in Info inside of GNU Emacs, you can evaluate each
#    of the following expressions by positioning the cursor after it and typing
#    @k{C-x C-e}.
   Si está leyendo esto dentro de GNU Emacs, puedes evaluar cada una de las
   siguientes expresiones colocando el cursor después de estas y pulsando @k{C-x
   C-e}.

#    ..src > elisp
   ..src > elisp
#      (buffer-name)
     (buffer-name)

#      (buffer-file-name)
     (buffer-file-name)
#    < src..
   < src..

#    When I do this in Info, the value returned by evaluating @c{(buffer-name)}
#    is @f{"*info*"}, and the value returned by evaluating
#    @c{(buffer-file-name)} is @f{nil}.
   Cuando hago esto en el búfer @f(*info*), el valor devuelto evaluando
   @c{(buffer-name)} es @f{"*info*"}, y el valor devuelto evaluando
   @c{(buffer-file-name)} es @f{nil}.

#    On the other hand, while I am writing this document, the value returned by
#    evaluating @c{(buffer-name)} is @c{"introduction.texinfo"}, and the value
#    returned by evaluating @c{(buffer-file-name)} is
#    @c{"/gnu/work/intro/introduction.texinfo"}.
   Por otro lado, mientras escribo este documento, el valor devuelto por la
   evaluación de @c{(buffer-name)} es @c{"introduction.texinfo"}, y el valor
   evaluando @c{(buffer-file-name)} es @c{"/gnu/work/intro/introduction.texinfo"}.

#    The former is the name of the buffer and the latter is the name of the
#    file. In Info, the buffer name is @f{"*info*"}. Info does not point to
#    any file, so the result of evaluating @c{(buffer-file-name)} is @f{nil}.
#    The symbol @c{nil} is from the Latin word for ‘nothing’; in this case, it
#    means that the buffer is not associated with any file.  (In Lisp, @c{nil}
#    is also used to mean ‘false’ and is a synonym for the empty list, @c{()}.)
   El primero es el nombre del búfer y el segundo es el nombre del
   fichero. En Info, el nombre del búfer es @f{"*info*"}. Info no apunta a
   ningún fichero, por lo que el resultado de evaluar @c{(buffer-file-name)}]
   es @f{nil}. El símbolo @c{nil} proviene del latin, significa ‘nada’; en
   este caso, significa que el búfer no está asociado con ningun fichero.
   (En Lisp, @c{nil} también se utiliza con el significado de ‘falso’ y es
   sinómino para la lista vacía, @c{()}.)

#    When I am writing, the name of my buffer is @c{"introduction.texinfo"}.
#    The name of the file to which it points is
#    @c{"/gnu/work/intro/introduction.texinfo"}.
   Al escribir esto, el nombre de mi búfer es @c{"introduction.texinfo"}. El
   nombre del fichero al que apunta es @c{"/gnu/work/intro/introduction.texinfo"}.

#    (In the expressions, the parentheses tell the Lisp interpreter to treat
#    @c{buffer-name} and @c{buffer-file-name} as functions; without the
#    parentheses, the interpreter would attempt to evaluate the symbols as
#    variables. See Section @l{#Variables}.)
   (En las expresiones, los paréntesis le indican al intérprete Lisp que trate a
   @c{buffer-name} y @c{buffer-file-name} como funciones; sin los paréntesis, el
   intérprete intentaría evaluar los símbolos como variables. Consulta la Sección
   @l{#Variables}.)

#    In spite of the distinction between files and buffers, you will often find
#    that people refer to a file when they mean a buffer and vice-verse.
#    Indeed, most people say, “I am editing a file,” rather than saying, “I am
#    editing a buffer which I will soon save to a file.”  It is almost always
#    clear from context what people mean. When dealing with computer programs,
#    however, it is important to keep the distinction in mind, since the
#    computer is not as smart as a person.
   A pesar de la distinción entre ficheros y búfers, con frecuencia encontraras
   personas referirse a un fichero cuando se refieren a un búfer y viceversa. De
   hecho, la mayoría de la gente dice, “Estoy editando un fichero”, en lugar de
   decir, “Estoy editando un búfer que pronto voy a guardar en un fichero”. Esto
   casi siempre queda claro a partir del contexto de lo que la gente quiere
   decir. No obstante, al tratar con programas de ordenador, es importante
   tener en cuenta la distinción, ya que el ordenador no es tan inteligente
   como una persona.

#    The word ‘buffer’, by the way, comes from
#    the meaning of the word as a cushion that deadens the force of a
#    collision. In early computers, a buffer cushioned the interaction between
#    files and the computer's central processing unit. The drums or tapes that
#    held a file and the central processing unit were pieces of equipment that
#    were very different from each other, working at their own speeds, in
#    spurts. The buffer made it possible for them to work together
#    effectively. Eventually, the buffer grew from being an intermediary, a
#    temporary holding place, to being the place where work is done. This
#    transformation is rather like that of a small seaport that grew into a
#    great city: once it was merely the place where cargo was warehoused
#    temporarily before being loaded onto ships; then it became a business and
#    cultural center in its own right.
   Por cierto, la palabra ‘búfer’, viene del significado de la palabra como un
   cojín que amortigua la fuerza de una colisión. En los primeros ordenadores,
   un búfer amortiguaba la interacción entre los ficheros y la unidad central de
   procesamiento del ordenador. Los tambores o cintas que contenian un fichero y
   la unidad de procesamiento eran equipos muy diferentes entre si, que
   trabajaban a su propia velocidad, por rafagas. El búfer hizo posible que
   ambos trabajaran juntos de manera efectiva. Con el tiempo, el búfer pasó de
   ser un intermediario, un lugar de almacenamiento temporal, a ser el lugar
   donde se realiza el trabajo. Esta transformación se parace bastante a la de
   un pequeño puerto que se convierte en una gran ciudad: una vez fué
   simplemente el lugar donde la carga se almacenaba temporalmente antes de ser
   cargada en los barcos; despues se convirtio en un centro comercial y cultural
   por derecho propio.

#    Not all buffers are associated with files. For example, a @f{*scratch*}
#    buffer does not visit any file. Similarly, a @f{*Help*} buffer is not
#    associated with any file.
   No todos los búfers están asociados con ficheros. Por ejemplo, el búfer
   @f(*scratch*) no visita ningun fichero. Del mismo modo, un búfer
   @f{*Help*} no está asociado a ningun fichero.

#    In the old days, when you lacked a @f{~/.emacs} file and started an Emacs
#    session by typing the command @c{emacs} alone, without naming any files,
#    Emacs started with the @f{*scratch*} buffer visible. Nowadays, you will
#    see a splash screen. You can follow one of the commands suggested on the
#    splash screen, visit a file, or press the spacebar to reach the
#    @f{*scratch*} buffer.
   En los viejos tiempos, cuando se carecia de un fichero @f{~/.emacs} y se
   iniciaba una sesión Emacs escribiendo unicamente el comando @c{emacs}, sin
   nombrar ningun fichero, Emacs iniciaba con el búfer @f{*scratch*}
   visible. Hoy en día, veras una pantalla de bienvenida. Puedes seguir uno de
   los comandos sugeridos en dicha pantalla, visitar un fichero, o presionar
   la barra de espacio para acceder al búfer @f{*scratch*}.

#    If you switch to the @f{*scratch*} buffer, type @c{(buffer-name)},
#    position the cursor after it, and then type @k{C-x C-e} to evaluate the
#    expression. The name @c{"*scratch*"} will be returned and will appear in
#    the echo area.  @c{"*scratch*"} is the name of the buffer. When you type
#    @c{(buffer-file-name)} in the @f{*scratch*} buffer and evaluate that,
#    @c{nil} will appear in the echo area, just as it does when you evaluate
#    @c{(buffer-file-name)} in Info.
   Si cambias al búfer @f{*scratch*}, escribe @c{(buffer-name)}, coloca el
   cursor al final de la expresión, y presiona @k{C-x C-e} para evaluar la
   expresión. El nombre @c{*scratch*} será devuelto y aparecerá en el área
   de eco. @c{*scratch*} es el nombre del búfer. Al escribir y evaluar
   @c{(buffer-file-name)} en el búfer @f{*scratch*}, aparecerá @c{nil} en el
   área de eco, igual que cuando evalúas @c{(buffer-file-name)} en Info.

#    Incidentally, if you are in the @f{*scratch*} buffer and want the value
#    returned by an expression to appear in the @f{*scratch*} buffer itself
#    rather than in the echo area, type @k{C-u C-x C-e} instead of @k{C-x C-e}.
#    This causes the value returned to appear after the expression. The buffer
#    will look like this:
   Por cierto, si estas en el búfer @f{*scratch*} y quieres que el
   valor devuelto por una expresión aparezca en el búfer en sí y no en el
   área de eco, presiona @k{C-u C-x C-e} en lugar de @k{C-x C-e}. Esto hace
   que el valor devuelto aparezca después de la expresión. El búfer se verá
   así:

#    ..example >
#      (buffer-name)"*scratch*"
#    < example..
   ..example >
     (buffer-name)"*scratch*"
   < example..

#    You cannot do this in Info since Info is read-only and it will not allow
#    you to change the contents of the buffer. But you can do this in any
#    buffer you can edit; and when you write code or documentation (such as
#    this book), this feature is very useful.
   No se puede hacer esto en Info ya que Info es de solo lectura y no se
   permitirá cambiar el contenido del búfer. Pero puedes hacer esto en
   cualquier búfer que puedas editar; y cuando escribes código o
   documentación (como este libro), esta caracteristica es muy útil.

# ** Getting Buffers
** Obtención de Búfers

#    The @c{buffer-name} function returns the @e{name} of the buffer; to get
#    the buffer @e{itself}, a different function is needed: the
#    @c{current-buffer} function. If you use this function in code, what you
#    get is the buffer itself.
   La función @c{buffer-name} devuelve el @e{nombre} del búfer; para obtener
   el búfer @e{en sí}, se necesita una función diferente: la función
   @c{current-buffer}. Si utilizas esta función en el código, lo que se
   obtiene es el búfer en sí.

#    A name and the object or entity to which the name refers are different
#    from each other. You are not your name. You are a person to whom others
#    refer by name. If you ask to speak to George and someone hands you a card
#    with the letters @'{G}, @'{e}, @'{o}, @'{r}, @'{g}, and @'{e} written on
#    it, you might be amused, but you would not be satisfied. You do not want
#    to speak to the name, but to the person to whom the name refers. A buffer
#    is similar: the name of the scratch buffer is @f{*scratch*}, but the name
#    is not the buffer. To get a buffer itself, you need to use a function
#    such as @c{current-buffer}.
   Un nombre y el objeto o entidad al que se refiere el nombre son
   diferentes entre si. Tu no eres tu nombre, eres una persona a la que se
   refieren los demas por tu nombre. Si pides hablar con Jorge y alguien te
   entrega una tarjeta con las letras @'{J}, @'{o}, @'{r}, @'{g}, y @'{e}
   escritas, podrias divertirte, pero no estarías satisfecho. No quieres
   hablar con el nombre, sino con la persona a la que se refiere el
   nombre. Un búfer es similar: el nombre del búfer scratch es
   @f{*scratch*}, pero el nombre no es el búfer. Para obtener un búfer en
   sí, es necesario utilizar una función como @c{current-buffer}.

#    However, there is a slight complication: if you evaluate
#    @c{current-buffer} in an expression on its own, as we will do here, what
#    you see is a printed representation of the name of the buffer without the
#    contents of the buffer. Emacs works this way for two reasons: the buffer
#    may be thousands of lines long––too long to be conveniently displayed;
#    and, another buffer may have the same contents but a different name, and
#    it is important to distinguish between them.
   Sin embargo, hay una ligera complicación: si evalúas @c{current-buffer} en
   una expresión por sí sola, como haremos aquí, lo que se ve es una
   representación impresa del nombre del búfer sin el contenido del búfer. Emacs
   funciona de esta forma por dos razones: el búfer puede contener miles de
   líneas––demasiado largo para mostrarse convenientemente; y, otro búfer
   puede tener el mismo contenido pero un nombre diferente, y es importante
   distinguir entre ellos.

#    Here is an expression containing the function:
   Aquí hay una expresión que contiene la función:

#    ..src > elisp
#      (current-buffer)
#    < src..
   ..src > elisp
     (current-buffer)
   < src..

#    If you evaluate this expression in Info in Emacs in the usual way,
#    @f{#<buffer *info*>} will appear in the echo area. The special format
#    indicates that the buffer itself is being returned, rather than just its
#    name.
   Si evalúas esta expresión en Info de la manera habitual, aparecerá
   @f{#<buffer *info*>} en el área de eco. El formato especial indica que se
   está devuendo el búfer en sí, en lugar de solo su nombre.

#    Incidentally, while you can type a number or symbol into a program, you
#    cannot do that with the printed representation of a buffer: the only way
#    to get a buffer itself is with a function such as @c{current-buffer}.
   Por cierto, si bien puedes escribir un número o símbolo en un programa, no
   se puede hacer esto con la representación impresa del búfer: la única
   manera de optener un búfer en sí mismo es con una función como
   @c{current-buffer}.

#    A related function is @c{other-buffer}. This returns the most recently
#    selected buffer other than the one you are in currently, not a printed
#    representation of its name. If you have recently switched back and forth
#    from the @f{*scratch*} buffer, @c{other-buffer} will return that buffer.
   Una función relacionada es @c{other-buffer}. Esta devuelve el último bufer
   seleccionado distinto al que te encuentras actualmente, no una
   representación impresa de su nombre. Si recientemente has ido y vuelto del
   búfer @f{*scratch*}, @c{other-buffer} devolverá ese búfer.

#    You can see this by evaluating the expression:
   Puedes ver esto evaluando la expresión:

#    ..src > elisp
#      (other-buffer)
#    < src..
   ..src > elisp
     (other-buffer)
   < src..

#    You should see @c{#<buffer *scratch*>} appear in the echo area, or the
#    name of whatever other buffer you switched back from most
#    recently@n{5}.
   Verás que @c{#<buffer *scratch*>} aparece en el área de eco, o el nombre de
   cualquier otro búfer al que allas cambiado anteriormente reciente@n{5}

# ** Switching Buffers
** Cambiando búfers

#    The @c{other-buffer} function actually provides a buffer when it is used
#    as an argument to a function that requires one. We can see this by using
#    @c{other-buffer} and @c{switch-to-buffer} to switch to a different buffer.
   La función @c{other-buffer} realmente proporciona un búfer cuando se
   utiliza como argumento de una función que requiera uno. Podemos ver esto
   usando @c{other-buffer} y @c{switch-to-buffer} para cambiar a un búfer
   diferente.

#    But first, a brief introduction to the @c{switch-to-buffer} function.
#    When you switched back and forth from Info to the @f{*scratch*} buffer to
#    evaluate @c{(buffer-name)}, you most likely typed @k{C-x b} and then typed
#    @f{*scratch*}@n{6} when prompted in the minibuffer for the name of the buffer to
#    which you wanted to switch. The keystrokes, @k{C-x b}, cause the Lisp
#    interpreter to evaluate the interactive function @c{switch-to-buffer}. As
#    we said before, this is how Emacs works: different keystrokes call or run
#    different functions. For example, @k{C-f} calls @c{forward-char}, @k{M-e}
#    calls @c{forward-sentence}, and so on.
   Pero primero, una breve introducción a la función @c{switch-to-buffer}.
   Cuando cambiaste de ida y vuelta de Info al búfer @f{*scratch*} para evaluar
   @c{(buffer-name)}, probablemente pulsaste @k{C-x b} y luego escribiste
   @f{*scratch*}@n{6} en el minibuffer cuando se solicito el nombre del
   buffer al que querias cambiar. El atajo, @k{C-x b}, hace que el intérprete
   Lisp evalúe la función interactiva @c{switch-to-buffer}. Como hemos dicho
   anteriormente, así es como funciona Emacs: diferentes atajos de teclado
   llaman o ejecutan diferentes funciones. Por ejemplo, @k{C-f} llama a
   @c{forward-char}, @k{M-e} llama a @c{forward-sentence}, etcétera.

#    By writing @c{switch-to-buffer} in an expression, and giving it a buffer
#    to switch to, we can switch buffers just the way @k{C-x b} does:
   Al escribir @c{switch-to-buffer} en una expresión, y darle un búfer al
   que cambiar, podemos cambiar de búfer tal y como lo hace @k{C-x b}.

#    ..src > elisp
#      (switch-to-buffer (other-buffer))
#    < src..
   ..src > elisp
     (switch-to-buffer (other-buffer))
   < src..

#    The symbol @c{switch-to-buffer} is the first element of the list, so the
#    Lisp interpreter will treat it as a function and carry out the
#    instructions that are attached to it. But before doing that, the
#    interpreter will note that @c{other-buffer} is inside parentheses and work
#    on that symbol first.  @c{other-buffer} is the first (and in this case,
#    the only) element of this list, so the Lisp interpreter calls or runs the
#    function. It returns another buffer. Next, the interpreter runs
#    @c{switch-to-buffer}, passing to it, as an argument, the other buffer,
#    which is what Emacs will switch to. If you are reading this in Info, try
#    this now. Evaluate the expression.  (To get back, type @k{C-x b
#    @k{RET}}.)@n{7}
   El símbolo @c{switch-to-buffer} es el primer elemento de la lista, por lo
   que el intérprete Lisp lo tratará como una función y llevara a cabo las
   instrucciones adjuntas al mismo. Pero antes de hacer esto, el intérprete
   observara que @c{other-buffer} está dentro de paréntesis y trabajara en
   este símbolo primero. @c{other-buffer} es el primer (y en este caso, el
   único) elemento de esta lista, por lo que el intérprete llama o ejecuta la
   función. Esto devuelve un búfer distinto al actual. A continuación, el
   intérprete ejecuta @c{switch-to-buffer}, pasando, como argumento, el
   búfer devuelto, que es al que Emacs cambiara. Si estás leyendo esto en
   Emacs, prueba ahora. Evalúa la expresión. (Para regresar, presiona @k{C-x b
   RET}.)@n{7}

#    In the programming examples in later sections of this document, you will
#    see the function @c{set-buffer} more often than @c{switch-to-buffer}.
#    This is because of a difference between computer programs and humans:
#    humans have eyes and expect to see the buffer on which they are working on
#    their computer terminals. This is so obvious, it almost goes without
#    saying. However, programs do not have eyes. When a computer program
#    works on a buffer, that buffer does not need to be visible on the screen.
   En los ejemplos de las secciones siguentes, veras con más frecuencia la
   función @c{set-buffer} que @c{switch-to-buffer}. Esto se debe a la
   diferencia entre los programas de ordenador y los seres humanos: los humanos
   tienen ojos y esperan ver el búfer en el que están trabajando en la
   terminal de su ordenador. Esto es tan evidente, que casi no hace falta decirlo. Sin
   embargo, los programas no tienen ojos. Cuando un programa de ordenador
   trabaja en un búfer, el búfer no necesita ser visible en la pantalla.

#    @c{switch-to-buffer} is designed for humans and does two different things:
#    it switches the buffer to which Emacs's attention is directed; and it
#    switches the buffer displayed in the window to the new buffer.
#    @c{set-buffer}, on the other hand, does only one thing: it switches the
#    attention of the computer program to a different buffer. The buffer on
#    the screen remains unchanged (of course, normally nothing happens there
#    until the command finishes running).
   @c{switch-to-buffer} está diseñado para humanos y hace dos cosas
   diferentes: cambia el búfer a el que Emacs dirige la atención; y cambia
   el búfer mostrado en la ventana al nuevo búfer. @c{set-buffer}, por otro
   lado, solo hace una cosa: cambia la atención del programa de ordenador a
   un búfer diferente. El búfer en la pantalla permanece sin cambios (por
   supuesto, normalmente no pasa nada hasta que el comando termina de
   ejecutarse).

#    Also, we have just introduced another jargon term, the word @:{call}.
#    When you evaluate a list in which the first symbol is a function, you are
#    calling that function. The use of the term comes from the notion of the
#    function as an entity that can do something for you if you ‘call’ it––just
#    as a plumber is an entity who can fix a leak if you call him or her.
   Además, acabamos introduciendo otro termino tecnico, la palabra
   @:{llamada}. Cuando se evalúa una lista en la que el primer símbolo es una
   función, se llama a esa función. El uso del término viene de la
   noción de la función como una entidad que puede algo hacer por ti si la
   ‘llamas’––al igual que un fontanero es una entidad que puede arreglar
   una fuga si lo llamas.

# ** Buffer Size and the Location of Point
** Tamaño del búfer y ubicación del punto

#    Finally, let's look at several rather simple functions, @c{buffer-size},
#    @c{point}, @c{point-min}, and @c{point-max}. These give information about
#    the size of a buffer and the location of point within it.
   Finalmente, veamos algunas funciones bastante simples, como @c{buffer-size},
   @c{point}, @c{point-min}, y @c{point-max}. Estas proporcionan información
   sobre el tamaño de un búfer y la ubicación del punto dentro de el.

#    The function @c{buffer-size} tells you the size of the current buffer;
#    that is, the function returns a count of the number of characters in the
#    buffer.
   La función @c{buffer-size} te dice el tamaño del búfer actual; es decir,
   la función devuelve un conteo del número de caracteres en el buffer.

#    ..src > elisp
#      (buffer-size)
#    < src..
   ..src > elisp
     (buffer-size)
   < src..

#    You can evaluate this in the usual way, by positioning the cursor after
#    the expression and typing @k{C-x C-e}.
   Puedes evaluar esto de la forma habitual, coloca el cursor después de la
   expresión y presiona @k{C-x C-e}.

#    In Emacs, the current position of the cursor is called @:{point}. The
#    expression @c{(point)} returns a number that tells you where the cursor is
#    located as a count of the number of characters from the beginning of the
#    buffer up to point.
   En Emacs, la posición actual del cursor se llama @:{punto}. La
   expresión @c{(point)} devuelve un número que indica donde esta situado el
   cursor como un conteo del número de caracteres desde el principio del
   búfer hasta el punto.

#    You can see the character count for point in this buffer by evaluating the
#    following expression in the usual way:
   Puedes ver el conteo de caracteres del punto para este búfer evaluando la
   siguiente expresión de la forma habitual:

#    ..src > elisp
#      (point)
#    < src..
   ..src > elisp
     (point)
   < src..

#    As I write this, the value of @c{point} is 65724. The @c{point} function
#    is frequently used in some of the examples later in this book.
   Mientras escribo esto, el valor de @c{point} es 65724. La función
   @c{point} se utiliza con frecuencia en algunos de los ejemplos mas
   adelante en este libro.

#    The value of point depends, of course, on its location within the buffer.
#    If you evaluate point in this spot, the number will be larger:
   El valor del punto depende, por supuesto, de su ubicacion dentro del
   búfer. Si evaluas el punto en este lugar, el número será mayor:

#    ..src > elisp
#      (point)
#    < src..
   ..src > elisp
     (point)
   < src..

#    For me, the value of point in this location is 66043, which means that
#    there are 319 characters (including spaces) between the two expressions.
#    (Doubtless, you will see different numbers, since I will have edited this
#    since I first evaluated point.)
   Para mí, el valor del punto en esta posición es 66043, lo que significa que
   hay 319 caracteres (incluyendo espacios) entre las dos expresiones.  (Sin
   duda, verás números diferentes, ya que lo habré editado desde que evalue el
   punto por primera vez.)

#    The function @c{point-min} is somewhat similar to @c{point}, but it
#    returns the value of the minimum permissible value of point in the current
#    buffer. This is the number 1 unless @:{narrowing} is in effect.
#    (Narrowing is a mechanism whereby you can restrict yourself, or a program,
#    to operations on just a part of a buffer. See Section @l{#Narrowing and
#    Widening}.)  Likewise, the function @c{point-max} returns the value of the
#    maximum permissible value of point in the current buffer.
   La función @c{point-min} es similar a @c{point}, pero devuelve el valor
   mínimo permitido del punto en el búfer actual. Este es el numero 1 a menos
   que @:{narrowing} esté en efecto. (Narrowing @%i{Reduccion} es un mecanismo
   mediante el cual puedes restringirte a ti mismo, o a un programa, a operar solo
   en un parte de un búfer. Consulta la Sección @l{#Reducir y Extender}.)  Del mismo
   modo, la función @c{point-max} devuelve el valor máximo permitido del punto
   en el búfer actual.

# ** Exercise
** Ejercicio

#    Find a file with which you are working and move towards its middle.
#    Find its buffer name, file name, length, and your position in the file.
   Busca un fichero en el que trabarjar y avanza hasta su mitad. Encuentra el
   nombre de búfer, el nombre del fichero, su tamaño, y la posición en el
   fichero.

# * How To Write Function Definitions
* Cómo escribir definiciones de funcion

#   When the Lisp interpreter evaluates a list, it looks to see whether the
#   first symbol on the list has a function definition attached to it; or, put
#   another way, whether the symbol points to a function definition. If it
#   does, the computer carries out the instructions in the definition. A
#   symbol that has a function definition is called, simply, a function
#   (although, properly speaking, the definition is the function and the symbol
#   refers to it.)
  Cuando el intérprete Lisp evalúa una lista, mira si el primer símbolo tiene
  una definición de funcion adjunta; o, dicho de otro modo, si el símbolo apunta
  a una definición de función. Si lo hace, el ordenador ejecuta las
  instrucciones de la definición. Un símbolo que tiene una
  definición de función se llamada, simplemente, una función (aunque hablando
  con propiedad, la definición es la función y el símbolo hace referencia a ella.)

#   All functions are defined in terms of other functions, except for a few
#   @:{primitive} functions that are written in the C programming language.
#   When you write functions' definitions, you will write them in Emacs Lisp
#   and use other functions as your building blocks. Some of the functions you
#   will use will themselves be written in Emacs Lisp (perhaps by you) and some
#   will be primitives written in C. The primitive functions are used exactly
#   like those written in Emacs Lisp and behave like them. They are written in
#   C so we can easily run GNU Emacs on any computer that has sufficient power
#   and can run C.
  Todas las funciones se defininen en términos de otras funciones, a
  excepción de algunas funciones @:{primitivas} que estan escritas en el lenguaje de
  programación C. Cuando escribas definiciones de funcion, debes
  escribirlas en Emacs Lisp y utilizar otras funciones como bloques de
  construcción. Algunas de las funciones que utilizaras estaran a su vez escritas
  en Emacs Lisp (quizás por tí) y otras serán primitivas escritas en C. Las
  funciones primitivas se usan exactamente igual que las escritas en Emacs
  Lisp y se comportan de igual forma. Están escritas en C para que podamos
  ejecutar facilmente GNU Emacs en cualquier ordenador que tenga la potencia
  suficiente y pueda ejecutar C.

#   Let me re-emphasize this: when you write code in Emacs Lisp, you do not
#   distinguish between the use of functions written in C and the use of
#   functions written in Emacs Lisp. The difference is irrelevant. I mention
#   the distinction only because it is interesting to know. Indeed, unless you
#   investigate, you won't know whether an already-written function is written
#   in Emacs Lisp or C.
  Permíteme volver a enfatizar esto: cuando se escribe código en Emacs Lisp, no
  se distinge entre el uso de funciones escritas en C y el uso de funciones
  escritas en Emacs Lisp. La diferencia es irrevelante. Menciono la distinción
  solo porque es interesante conocerla. De hecho, a menos de que investigues, no
  sabras si una función ya escrita esta en Emacs Lisp o en C.

# ** The @c{defun} Special Form
** La forma especial @c{defun}

#    In Lisp, a symbol such as @c{mark-whole-buffer} has code attached to it
#    that tells the computer what to do when the function is called. This code
#    is called the @:{function definition} and is created by evaluating a Lisp
#    expression that starts with the symbol @c{defun} (which is an abbreviation
#    for @e{define function}). Because @c{defun} does not evaluate its
#    arguments in the usual way, it is called a @:{special form}.
   En Lisp, un símbolo como @c{mark-whole-buffer} tiene un código adjunto que le
   dice al ordenador que hacer cuando se invoca la función. Este código se
   denomina la @:{definición de función} y se crea evaluando una expresión Lisp
   que comienza con el símbolo @c{defun} (que es una abreviatura para @e{define
   function} @%i(definir función)). Debido a que @c{defun} no evalúa sus
   argumentos de la manera habitual, se le llama una @:{forma especial}.

#    In subsequent sections, we will look at function definitions from the
#    Emacs source code, such as @c{mark-whole-buffer}. In this section, we
#    will describe a simple function definition so you can see how it looks.
#    This function definition uses arithmetic because it makes for a simple
#    example. Some people dislike examples using arithmetic; however, if you
#    are such a person, do not despair. Hardly any of the code we will study
#    in the remainder of this introduction involves arithmetic or mathematics.
#    The examples mostly involve text in one way or another.
   En las siguientes secciones, veremos algunas definiciones de función presentes
   dentro del código fuente de Emacs, como @c{mark-whole-buffer}.
   En esta sección, describiremos una definición de función sencilla para que
   puedas ver su aspecto. Esta definición de función usa aritmética porque es
   un ejemplo simple. A algunas personas les disgustan los ejemplos que usan
   aritmética; sin embargo, si eres una persona asi, no te desesperes. Casi
   ningun codigo a estudiar en el resto de esta introducción implica
   aritmética o matemáticas. Los ejemplos involucran principalmente texto de
   una forma u otra.

#    A function definition has up to five parts following the word @c{defun}:
   Una definición de función tiene hasta cinco partes despues de la
   palabra @c{defun}:

#    1. The name of the symbol to which the function definition should be
#       attached.
   1. El nombre del símbolo al se debe vincular la definición de función.

#    2. A list of the arguments that will be passed to the function. If no
#       arguments will be passed to the function, this is an empty list,
#       @c{()}.
   2. Una lista de los argumentos que se pasan a la función. Si no hay
      argumentos que pasar a la función, tendremos una lista vacía, @c{()}.

#    3. Documentation describing the function.  (Technically optional, but
#       strongly recommended.)
   3. Documentación que describe la función. (Técnicamente opcional, pero
      muy recomendable.)

#    4. Optionally, an expression to make the function interactive so you can
#       use it by typing @k{M-x} and then the name of the function; or by
#       typing an appropriate key or keychord.
   4. Opcionalmente, una expresión para hacer que la función sea interactiva, de
      manera que se puede utilizarla presionando @k{M-x} seguido del nombre de la
      función; o pulsando una tecla o atajo de teclado.

#    5. The code that instructs the computer what to do: the @:{body} of the
#       function definition.
   5. El código que indica a el ordenador qué hacer: el @:{cuerpo} de la
      definición de función.

#    It is helpful to think of the five parts of a function definition as being
#    organized in a template, with slots for each part:
   Es útil pensar que las cinco partes de una definición de función estan
   organizadas como en una plantilla, con ranuras para cada parte:

#    ..src > elisp
#      (defun function-name (arguments…)
#        "optional-documentation…"
#        (interactive argument-passing-info)     ; optional
#        body…)
#    < src..
   ..src > elisp
     (defun nombre-de-función (argumentos…)
       "documentación-opcional…"
       (interactive informacion-de-paso-de-argumentos)     ; opcional
       cuerpo…)
   < src..

#    As an example, here is the code for a function that multiplies its
#    argument by 7.  (This example is not interactive. See Section @l{#Make a
#    Function Interactive}, for that information.)
   A modo de ejemplo, aquí está el código de una función que multiplica su
   argumento por 7. (Este ejemplo no es interactivo. Consulta la Sección @l{#Crear una
   Función Interactiva}, para obtener esa información.)

#    ..src > elisp
#      (defun multiply-by-seven (number)
#        "Multiply NUMBER by seven."
#        (* 7 number))
#    < src..
   ..src > elisp
     (defun multiplicar-por-siete (numero)
       "Multiplica NUMERO por siete."
       (* 7 numero))
   < src..

#    This definition begins with a parenthesis and the symbol @c{defun},
#    followed by the name of the function.
   Esta definición comienza con un paréntesis y el símbolo @c{defun} seguido
   por el nombre de la función.

#    The name of the function is followed by a list that contains the arguments
#    that will be passed to the function. This list is called the @:{argument
#    list}. In this example, the list has only one element, the symbol,
#    @c{number}. When the function is used, the symbol will be bound to the
#    value that is used as the argument to the function.
   El nombre de la función es seguido por una lista que contiene los
   argumentos que seran pasados a la función. Esta lista se llama @:{lista de
   argumentos}. En este ejemplo, la lista solo tiene un elemento, el símbolo
   @c{numero}. Cuando se utiliza la función, el símbolo sera asociado al
   valor que se utiliza como argumento de la función.

#    Instead of choosing the word @c{number} for the name of the argument, I
#    could have picked any other name. For example, I could have chosen the
#    word @c{multiplicand}. I picked the word ‘number’ because it tells what
#    kind of value is intended for this slot; but I could just as well have
#    chosen the word ‘multiplicand’ to indicate the role that the value placed
#    in this slot will play in the workings of the function. I could have
#    called it @c{foogle}, but that would have been a bad choice because it
#    would not tell humans what it means. The choice of name is up to the
#    programmer and should be chosen to make the meaning of the function clear.
   En lugar de elegir la palabra @c{numero} para el nombre del argumento,
   podría haber escogido cualquier otro nombre. Por ejemplo, la palabra
   @c{multiplicando}. Escogi la palabra ‘numero’ porque indica qué tipo de
   valor se pretende para este espacio; pero podría haber elegido
   ‘multiplicando’ para indicar el papel que jugara el valor en el
   funcionamiento de la función. Podría haberlo llamado @c{foogle}, pero
   habría sido una mala elección, ya que no comunicaria a los humanos qué
   significa. La elección del nombre es responsabilidad del programador y
   debe elegirse para hacer que el significado de la función quede claro.

#    Indeed, you can choose any name you wish for a symbol in an argument list,
#    even the name of a symbol used in some other function: the name you use in
#    an argument list is private to that particular definition. In that
#    definition, the name refers to a different entity than any use of the same
#    name outside the function definition. Suppose you have a nick-name
#    ‘Shorty’ in your family; when your family members refer to ‘Shorty’, they
#    mean you. But outside your family, in a movie, for example, the name
#    ‘Shorty’ refers to someone else. Because a name in an argument list is
#    private to the function definition, you can change the value of such a
#    symbol inside the body of a function without changing its value outside
#    the function. The effect is similar to that produced by a @c{let}
#    expression.  (See Section @l{#@c{let}}.)
   De hecho, puedes elegir cualquier nombre que desees para un símbolo en una
   lista de argumentos, incluso el nombre de un símbolo utilizado en alguna otra
   función: el nombre que utilices en una lista de argumentos es privado
   para esa definición particular. En esta definición, el nombre hace
   referenecia a una entidad diferente a cualquiera que utilice el mismo
   nombre fuera de la definición de función. Supón que tu familia te apodan
   ‘Enano’; cuando tus familiares digan ‘Enano’, queren hacer referencia a
   ti. Pero fuera de tu familia, en una película, por ejemplo, el nombre
   ‘Enano’ se refiere a alguien más. Debido a que el nombre en una lista de
   argumentos es privado de la definición de la función, se puede cambiar
   el valor de un símbolo dentro del cuerpo de una función sin cambiar su
   valor fuera de la función. El efecto es similar al producido por la
   expresión @c{let}. (Consulta la sección @l{#@c(let)}.)

#    The argument list is followed by the documentation string that describes
#    the function. This is what you see when you type @k{C-h f} and the name
#    of a function. Incidentally, when you write a documentation string like
#    this, you should make the first line a complete sentence since some
#    commands, such as @c{apropos}, print only the first line of a multi-line
#    documentation string. Also, you should not indent the second line of a
#    documentation string, if you have one, because that looks odd when you use
#    @k{C-h f} @%c(describe-function). The documentation string is optional,
#    but it is so useful, it should be included in almost every function you
#    write.
   La lista de argumentos es seguida por la cadena de documentación que
   describe la función. Esto es lo ves cuando presionas @k{C-h f} y escribes
   el nombre de una función. Por cierto, cuando escribas una cadena de
   documentación como esta, debes confeccionar la primera linea como una
   frace completa ya que algunos comandos, como @c{apropos}, solo imprimen
   la primer línea de una cadena de documentación de varias líneas.
   Ademas, no debes indentar la segunda línea de la cadena de documentación,
   si tienes una, porque se ve extraño al utilizar @k{C-h f}
   @%c(describe-function). La cadena de documentación es opcional, pero es
   tan útil, que debería incluirse en casi cualquier función que escribas.

#    The third line of the example consists of the body of the function
#    definition.  (Most functions' definitions, of course, are longer than
#    this.)  In this function, the body is the list, @c{(* 7 number)}, which
#    says to multiply the value of @c{number} by 7.  (In Emacs Lisp, @c{*} is
#    the function for multiplication, just as @c{+} is the function for
#    addition.)
   La tercer línea del ejemplo consiste en el cuerpo de la definición de
   función. (La mayoría de las definiciones de funcion, claro esta, son más
   extensas que esto.) En esta función, el cuerpo es la lista, @c{(* 7
   numero)}, que indica multiplicar el valor de @c{numero} por 7. (En Emacs
   Lisp, @c{*} es la función para multiplicar, al igual que @c{+} es la
   función para sumar.

#    When you use the @c{multiply-by-seven} function, the argument @c{number}
#    evaluates to the actual number you want used. Here is an example that
#    shows how @c{multiply-by-seven} is used; but don't try to evaluate this
#    yet!
   Cuando se utiliza la función @c{multiplicar-por-siete}, el argumento
   @c{numero} se evalúa al número que desees usar. He aquí un ejemplo que
   muestra como utilizar @c{multiplicar-por-siete}; ¡pero no trates de evaluar
   esto primero!.

#    ..src > elisp
#      (multiply-by-seven 3)
#    < src..
   ..src > elisp
     (multiplicar-por-siete 3)
   < src..

#    The symbol @c{number}, specified in the function definition in the next
#    section, is given or “bound to” the value 3 in the actual use of the
#    function. Note that although @c{number} was inside parentheses in the
#    function definition, the argument passed to the @c{multiply-by-seven}
#    function is not in parentheses. The parentheses are written in the
#    function definition so the computer can figure out where the argument list
#    ends and the rest of the function definition begins.
   El símbolo @c{numero}, especificado en la definición de función en la
   siguiente sección, se da o “une a” el valor 3 en el uso real de la
   función. Observa que aunque @c{numero} estaba dentro de paréntesis en la
   definición de función, el argumento pasado a la función
   @c{multiplicar-por-siete} no está entre paréntesis. Los paréntesis se
   escriben en la definición de función para que el ordenador pueda averiguar
   donde termina la lista de argumentos y donde inicia el resto de la definición de
   función.

#    If you evaluate this example, you are likely to get an error message.  (Go
#    ahead, try it!)  This is because we have written the function definition,
#    but not yet told the computer about the definition––we have not yet
#    installed (or ‘loaded’) the function definition in Emacs. Installing a
#    function is the process that tells the Lisp interpreter the definition of
#    the function. Installation is described in the next section.
   Si evalúas este ejemplo, es probable que obtengas un mensaje de error.
   (¡adelante, intentalo!) Esto se debe a que hemos escrito la definición de
   función, pero aún no se ha comunicado al ordenador sobre la definición––aun no
   hemos instalado (o ‘cargado’) la definición de función en Emacs. Instalar
   una función es el proceso de comunicar al intérprete Lisp la definición de
   la función. La instalación se describe en la siguiente sección.

# ** Install a Function Definition
** Instalar una definición de función

#    If you are reading this inside of Info in Emacs, you can try out the
#    @c{multiply-by-seven} function by first evaluating the function definition
#    and then evaluating @c{(multiply-by-seven 3)}. A copy of the function
#    definition follows. Place the cursor after the last parenthesis of the
#    function definition and type @k{C-x C-e}. When you do this,
#    @c{multiply-by-seven} will appear in the echo area.  (What this means is
#    that when a function definition is evaluated, the value it returns is the
#    name of the defined function.)  At the same time, this action installs the
#    function definition.
   Si estás leyendo esto dentro en Emacs, puedes probar la función
   @c{multiplicar-por-siete} evaluando en primer lugar la definición de función y
   luego evaluando @c{(multiplicar-por-siete 3)}. Hay una copia de la
   definición a continuación. Coloca el cursor después del último paréntesis
   de la definición de función y presiona @k{C-x C-e}. Al hacer esto,
   @c{multiplicar-por-siete} aparecerá en el área de eco. (Esto significa
   que cuando se evalua una definición de función, el valor devuelto es
   el nombre de la función definida.) Al mismo tiempo, esta acción instala la
   definición de función.

#    ..src > elisp
#      (defun multiply-by-seven (number)
#        "Multiply NUMBER by seven."
#        (* 7 number))
#    < src..
   ..src > elisp
     (defun multiplicar-por-siete (numero)
       "Multiplica NUMERO por siete."
       (* 7 numero))
   < src..

#    By evaluating this @c{defun}, you have just installed
#    @c{multiply-by-seven} in Emacs. The function is now just as much a part
#    of Emacs as @c{forward-word} or any other editing function you use.
#    (@c{multiply-by-seven} will stay installed until you quit Emacs. To
#    reload code automatically whenever you start Emacs, see Section @l{#Install
#    Code Permanently}.)
   Al evaluar este @c{defun}, estas instanlado @c{multiplicar-por-siete} en
   Emacs. La función ahora es una parte de Emacs tanto como
   @c{forward-word} o cualquier otra función de edición que utilices.
   (@c{multiplicar-por-siete} permanecera instalado hasta que salgas de
   Emacs. Para volver a cargar el código automáticamente cada vez que inicie
   Emacs, revisa la sección @l{#Instalar Código Permanentemente}.)

#    You can see the effect of installing @c{multiply-by-seven} by evaluating
#    the following sample. Place the cursor after the following expression and
#    type @k{C-x C-e}. The number 21 will appear in the echo area.
   Puedes ver el efecto de instalar @c{multiplicar-por-siete} evaluando el
   siguiente ejemplo. Coloca el cursor después de la siguiente expresión y
   presiona @k{C-x C-e}. El número 21 aparacerá en el área de eco.

#    ..src > elisp
#      (multiply-by-seven 3)
#    < src..
   ..src > elisp
     (multiplicar-por-siete 3)
   < src..

#    If you wish, you can read the documentation for the function by typing
#    @k{C-h f} @%c(describe-function) and then the name of the function,
#    @c{multiply-by-seven}. When you do this, a @f{*Help*} window will appear
#    on your screen that says:
   Si lo deseas, puedes leer la documentación de la función presiona @k{C-h
   f} @%c(describe-function) y luego escribe el nombre de la función,
   @c{multiplicar-por-siete}. Al hacer esto, aparecerá una ventana @f{*Help*}
   en tu pantalla diciendo:

#    ..example >
   ..example >
#      multiply-by-seven is a Lisp function.
#      (multiply-by-seven NUMBER)
     multiplicar-por-siete is a Lisp function.
     (multiplicar-por-siete NUMERO)

#      Multiply NUMBER by seven.
     Multiplica NUMERO por siete.
#    < example..
   < example..

#    (To return to a single window on your screen, type @k{C-x 1}.)
   (Para volver a una sola ventana en tu pantalla, presiona @k{C-x 1}.)

# *** Change a Function Definition
*** Cambiar una definición de función

#     If you want to change the code in @c{multiply-by-seven}, just rewrite it.
#     To install the new version in place of the old one, evaluate the function
#     definition again. This is how you modify code in Emacs. It is very
#     simple.
    Si quieres modificar el código de @c{multiplicar-por-siete}, simplemente
    reescribelo. Para instalar la nueva versión en lugar de la anterior, evalúa
    nuevamente la definición de la función. Esta, es la forma de modificar el
    código en Emacs. Es muy sencillo,

#     As an example, you can change the @c{multiply-by-seven} function to add
#     the number to itself seven times instead of multiplying the number by
#     seven. It produces the same answer, but by a different path. At the
#     same time, we will add a comment to the code; a comment is text that the
#     Lisp interpreter ignores, but that a human reader may find useful or
#     enlightening. The comment is that this is the “second version”.
    A modo de ejemplo, puedes cambiar la función @c{multiplicar-por-siete}
    para sumar el número a sí mismo siete veces en lugar de multiplicar el
    número por siete. Esto produce el mismo resultado, pero por una ruta
    diferente. Al mismo tiempo, añadiremos un comentario al codigo; un
    comentario es texto que el intérprete Lisp ignora, pero un lector humano
    puede encontrar útil o esclarecedor. El comentario es, que esta es la
    “segunda versión”.

#     ..src > elisp
#       (defun multiply-by-seven (number)       ; Second version.
#         "Multiply NUMBER by seven."
#         (+ number number number number number number number))
#     < src..
    ..src > elisp
      (defun multiplicar-por-siete (numero)       ; Segunda versión.
        "Multiplica NUMERO por siete."
        (+ numero numero numero numero numero numero numero))
    < src..

#     The comment follows a semicolon, @'{;}. In Lisp, everything on a line
#     that follows a semicolon is a comment. The end of the line is the end of
#     the comment. To stretch a comment over two or more lines, begin each
#     line with a semicolon.
    El comentario sigue a un punto y coma, @'{;}. En Lisp cualquier cosa en
    una línea despues de un punto y coma es un comentario. El fin de la línea
    es el fin del comentario. Para extender un comentario por dos o más
    líneas, inicia cada línea con un punto y coma.

#     See Section @l{#Beginning a @f{.emacs} File}, and Section
#     @l{elisp.html#Comments<>Comments} in @e{The GNU Emacs Lisp Reference Manual}, for
#     more about comments.
    Consulta las Secciónes @l(#Empieza por un fichero @f{.emacs}) y
    @l{elisp.html#Comments<>Comentarios} en @e(El Manual de Referencia de GNU
    Emacs Lisp), para más informacion sobre los comentarios.

#     You can install this version of the @c{multiply-by-seven} function by
#     evaluating it in the same way you evaluated the first function: place the
#     cursor after the last parenthesis and type @k{C-x C-e}.
    Puedes instalar esta versión de @c{multiplicar-por-siete} evaluándo esta
    del mismo modo en que evaluaste la primer función: coloca el cursor
    después del último paréntesis y presiona @k{C-x C-e}.

#     In summary, this is how you write code in Emacs Lisp: you write a
#     function; install it; test it; and then make fixes or enhancements and
#     install it again.
    En resumen, asi es como puedes escribir código en Emacs Lisp: escribes una
    función; la instalas; la pruebas; luego haces correcciones o mejoras y la
    vuelves a instalar.

# ** Make a Function Interactive
** Crear una función interactiva

#    You make a function interactive by placing a list that begins with the
#    special form @c{interactive} immediately after the documentation. A user
#    can invoke an interactive function by typing @k{M-x} and then the name of
#    the function; or by typing the keys to which it is bound, for example, by
#    typing @k{C-n} for @c{next-line} or @k{C-x h} for @c{mark-whole-buffer}.
   Puedes hacer a una función interactiva colocando una lista que inicia con la
   forma especial @c{interactive} inmediatamente después de la documentación.
   Un usuario puede invocar una función interactiva con @k{M-x} seguido del
   nombre de la función; o con un atajo de teclado ligado a esta, por
   ejemplo, presionando @k{C-n} para @c{next-line} o @k{C-x h} para
   @c{mark-whole-buffer}.

#    Interestingly, when you call an interactive function interactively, the
#    value returned is not automatically displayed in the echo area. This is
#    because you often call an interactive function for its side effects, such
#    as moving forward by a word or line, and not for the value returned. If
#    the returned value were displayed in the echo area each time you typed a
#    key, it would be very distracting.
   Cusionamente, cuando se llama a una función interactiva interactivamente, el
   valor devuelto no se muestra automáticamente en el área de eco. Esto se debe
   a que a menudo se llama a una función interactiva por sus efectos
   secundarios, como avanzar hacia adelante una palabra o una línea,
   y no por el valor devuelto. Si el valor devuelto se mostrara en el área
   de eco cada vez que presionas una tecla, seria muy molesto.

#    Both the use of the special form @c{interactive} and one way to display a
#    value in the echo area can be illustrated by creating an interactive
#    version of @c{multiply-by-seven}.
   Tanto el uso de la forma especial @c{interactive} y la forma de mostrar
   un valor en el área de eco se pueden ilustrar creando una versión
   interactiva de @c{multiplicar-por-siete}.

#    Here is the code:
   Aquí está el código:

#    ..src > elisp
#      (defun multiply-by-seven (number)       ; Interactive version.
#        "Multiply NUMBER by seven."
#        (interactive "p")
#        (message "The result is %d" (* 7 number)))
#    < src..
   ..src > elisp
     (defun multiplicar-por-siete (numero)       ; Versión Interactiva.
       "Multiplica NUMERO por siete."
       (interactive "p")
       (message "El resultado es %d" (* 7 numero)))
   < src..

#    You can install this code by placing your cursor after it and typing
#    @k{C-x C-e}. The name of the function will appear in your echo area.
#    Then, you can use this code by typing @k{C-u} and a number and then typing
#    @k{M-x multiply-by-seven} and pressing @k{RET}. The phrase @'{The result
#    is …} followed by the product will appear in the echo area.
   Para instalar este código, coloca el cursor después del ultimo parentesis y
   presiona @k{C-x C-e}. El nombre de la función aparecerá en el área de eco.  A
   continuacion, puedes utilizar este código al presionar @k{C-u} segudo de un
   número, luego @k{M-x multiplicar-por-siete} y finalmente @k{RET}. En el área
   de eco aparecerá la frase @'{El resultado es …} seguida por el producto.

#    Speaking more generally, you invoke a function like this in either of two
#    ways:
   Hablando en terminos mas generales, puedes invocar una función como ésta
   de dos maneras:

#    1. By typing a prefix argument that contains the number to be passed, and
#       then typing @k{M-x} and the name of the function, as with @k{C-u 3 M-x
#       forward-sentence}; or,
   1. Escribiendo un argumento prefijo que contenga el número a pasar, y luego
      presionar @k{M-x} y el nombre de la función, como ocurre con
      @k{C-u 3 M-x forward-sentence}; o,

#    2. By typing whatever key or keychord the function is bound to, as with
#       @k{C-u 3 M-e}.
   2. Pulsando cualquier tecla o atajo de teclado ligado a la función, como
      ocurre con @k{C-u 3 M-e}.

#    Both the examples just mentioned work identically to move point forward
#    three sentences.  (Since @c{multiply-by-seven} is not bound to a key, it
#    could not be used as an example of key binding.)
   Ambos ejemplos operan de forma identica moviendo el punto hacia adelante
   tres oraciones. (Ya que @c{multiply-by-seven} no esta ligado a un atajo, no
   se puede utilizar como ejemplo.)

#    (See Section @l{#Some Keybindings}, to learn how to bind a command to a
#    key.)
   (Consulta la Seccion @l{#Algunos Atajos de teclado}, para aprender como vincular un
   comando a una atajo.)

#    A prefix argument is passed to an interactive function by typing the
#    @k{META} key followed by a number, for example, @k{M-3 M-e}, or by typing
#    @k{C-u} and then a number, for example, @k{C-u 3 M-e} (if you type @k{C-u}
#    without a number, it defaults to 4).
   Un argumento prefijo se pasa a una función interactiva pulsando la tecla
   @k{META} seguida de un número, por ejemplo, @k{M-3 M-e}, o con @k{C-u} y
   luego un número, por ejemplo, @k{C-u 3 M-e} (si presionas @k{C-u} sin
   ningun número, el valor por defecto es 4).

# *** An Interactive @c{multiply-by-seven}
*** @c{multiplicar-por-siete} interactivo

#     Let's look at the use of the special form @c{interactive} and then at the
#     function @c{message} in the interactive version of @c{multiply-by-seven}.
#     You will recall that the function definition looks like this:
    Veamos es uso de la forma especial @c{interactive} y luego la función
    @c{message} en la versión interactiva de @c{multiplicar-por-siete}.
    Recordaras que la definición de función tiene el siguiente aspecto:

#     ..src > elisp
#       (defun multiply-by-seven (number)       ; Interactive version.
#         "Multiply NUMBER by seven."
#         (interactive "p")
#         (message "The result is %d" (* 7 number)))
#     < src..
    ..src > elisp
      (defun multiplicar-por-siete (numero)       ; Versión Interactiva.
        "Multiplica NUMERO por siete."
        (interactive "p")
        (message "El resultado es %d" (* 7 numero)))
    < src..

#     In this function, the expression, @c{(interactive "p")}, is a list of two
#     elements. The @c{"p"} tells Emacs to pass the prefix argument to the
#     function and use its value for the argument of the function.
    En esta función, la expresión, @c{(interactive "p")}, es una lista de dos
    elementos. La @c{"p"} le indica a Emacs que debe pasar el argumento
    prefijo a la función y utilizar este valor para el argumento de la
    función.

#     The argument will be a number. This means that the symbol @c{number}
#     will be bound to a number in the line:
    El argumento debe ser un número. Esto significa que el símbolo @c{numero}
    estara asociado a un número en la línea:

#     ..src > elisp
#       (message "The result is %d" (* 7 number))
#     < src..
    ..src > elisp
      (message "El resultado es %d" (* 7 numero))
    < src..

#     For example, if your prefix argument is 5, the Lisp interpreter will
#     evaluate the line as if it were:
    Por ejemplo, si tu argumento prefijo es 5, el intérprete Lisp evaluará la
    línea como si fuera:

#     ..src > elisp
#       (message "The result is %d" (* 7 5))
#     < src..
    ..src > elisp
      (message "El resultado es %d" (* 7 5))
    < src..

#     (If you are reading this in GNU Emacs, you can evaluate this expression
#     yourself.)  First, the interpreter will evaluate the inner list, which is
#     @c{(* 7 5)}. This returns a value of 35. Next, it will evaluate the
#     outer list, passing the values of the second and subsequent elements of
#     the list to the function @c{message}.
    (Si estás leyendo esto en GNU Emacs, puedes evaluar esta expresión por ti
    mismo.) Primero, el intérprete evaluará la lista interna, que es @c{(* 7
    5)}. Esto devuelve un valor de 35. A continuación, se evaluará la lista
    externa, pasando los valores del segundo y posteriores elementos de la
    lista a la función @c{message}.

#     As we have seen, @c{message} is an Emacs Lisp function especially
#     designed for sending a one line message to a user.  (See Section @l{#The
#     @c{message} function}.)  In summary, the @c{message} function prints its
#     first argument in the echo area as is, except for occurrences of @'c{%d}
#     or @'c{%s} (and various other %-sequences which we have not mentioned).
#     When it sees a control sequence, the function looks to the second or
#     subsequent arguments and prints the value of the argument in the location
#     in the string where the control sequence is located.
    Como hemos visto, @c{message} es una función Emacs Lisp especialmente
    diseñada para enviar un mensaje de una línea al usuario. (Consulta la Seccion
    @l{#La función @c{message}}.) En resumen, la función @c{message} imprime su
    primer argumento en el área de eco tal cual, excepto para las ocurrencias de
    @'c{%d}, o @'c{%s} (y varias otras secuencias de control que no hemos
    mencionado). Cuando aparece una secuencia de control, la función busca
    el segundo argumento o los siguientes e imprime el valor del argumento en
    la ubicación donde se encuartra la secuencia de control.

#     In the interactive @c{multiply-by-seven} function, the control string is
#     @'c{%d}, which requires a number, and the value returned by evaluating
#     @c{(* 7 5)} is the number 35. Consequently, the number 35 is printed in
#     place of the @'c{%d} and the message is @'{The result is 35}.
    En la función interactiva @c{multiplicar-por-siete}, la cadena de
    control es @'c{%d}, que requiere un número, y el valor devuelto por la
    evaluación de @c{(* 7 5)} es el número 35. Por consiguiente, el número 35
    se imprime en lugar de @'c{%d} y el mensaje es @'{El resultado es 35}.

#     (Note that when you call the function @c{multiply-by-seven}, the message
#     is printed without quotes, but when you call @c{message}, the text is
#     printed in double quotes. This is because the value returned by
#     @c{message} is what appears in the echo area when you evaluate an
#     expression whose first element is @c{message}; but when embedded in a
#     function, @c{message} prints the text as a side effect without quotes.)
    (Observa que cuando llamas a la función @c{multiplicar-por-siete}, el
    mensaje se imprime sin comillas, pero cuando llamas a @c{message}, el
    texto se imprime entre comillas. Esto se debe a que el valor devuelto por
    @c{message} aparece en el área de eco cuando se evalúa una expresión cuyo
    primer elemento es @c{message}; pero si se integra en una función,
    @c{message} imprime el texto como un efecto secundario sin las comillas.)

# ** Different Options for @c{interactive}
** Diferentes opciones para @c{interactive}

#    In the example, @c{multiply-by-seven} used @c{"p"} as the argument to
#    @c{interactive}. This argument told Emacs to interpret your typing either
#    @k{C-u} followed by a number or @k{META} followed by a number as a command
#    to pass that number to the function as its argument. Emacs has more than
#    twenty characters predefined for use with @c{interactive}. In almost
#    every case, one of these options will enable you to pass the right
#    information interactively to a function.  (See Section
#    @l{elisp.html#Interactive Codes<>Code Characters for @c{interactive}} in @e{The
#    GNU Emacs Lisp Reference Manual}.)
   En el ejemplo, @c{multiplicar-por-siete} utilizo @c{"p"} como el
   argumento para @c{interactive}. Este argumento le indica a Emacs que
   interpretara cualquer cosa que escribas despues de @k{C-u} o del comando
   @k{META} como un numero que sera el argumento a pasar a la funcion. Emacs
   tiene más de veinte caracteres predefinidos para usar con @c{interactive}.
   En casi todos los casos, una de estas opciones te permitira pasar la
   información correcta de forma interactiva a una función. (Consulta la Seccion
   @l{elisp.html#Interactive Codes<>Codigo de Caracteres para @c{interactive}} en @e(El
   Manual de Referencia de GNU Emacs Lisp)).

#    Consider the function @c{zap-to-char}. Its interactive expression is
   Considera la función @c{zap-to-char}. Su expresión interactiva es

#    ..src > elisp
#      (interactive "p\ncZap to char: ")
#    < src..
   ..src > elisp
     (interactive "p\ncZap to char: ")
   < src..

#    The first part of the argument to @c{interactive} is @'{p}, with which you
#    are already familiar. This argument tells Emacs to interpret a ‘prefix’,
#    as a number to be passed to the function. You can specify a prefix either
#    by typing @k{C-u} followed by a number or by typing @k{META} followed by a
#    number. The prefix is the number of specified characters. Thus, if your
#    prefix is three and the specified character is @'{x}, then you will delete
#    all the text up to and including the third next @'{x}. If you do not set
#    a prefix, then you delete all the text up to and including the specified
#    character, but no more.
   La primer parte del argumento de @c{interactive} es @'{p}, con el que ya
   estás familiarizado. Este argumento le dice a Emacs que interprete un
   ‘prefijo’, como un número que se pasa a la función. Puedes especificar un
   prefijo presionando @k{C-u} seguido de un número o igualmente con @k{META}
   seguido por un número. El prefijo es un número de caracteres especifico. De
   este modo, si el prefijo es tres y el caracter especificado es @'{x},
   entonces se borrará todo el texto hasta e incluido el tercer @'{x}
   siguiente. Si no se establece un prefijo, entonces borras todo el texto hasta
   e incluido el carácter especificado, pero no más.

#    The @'{c} tells the function the name of the character to which to delete.
   La @'{c} le dice a la función el nombre del carácter que va a eliminar.

#    More formally, a function with two or more arguments can have information
#    passed to each argument by adding parts to the string that follows
#    @c{interactive}. When you do this, the information is passed to each
#    argument in the same order it is specified in the @c{interactive} list.
#    In the string, each part is separated from the next part by a @'{\n},
#    which is a newline. For example, you can follow @'{p} with a @'{\n} and
#    an @'{cZap to char: }. This causes Emacs to pass the value of the
#    prefix argument (if there is one) and the character.
   Más formalmente, una función con dos o más argumentos puede tener
   información que pasa a cada argumento añadiendo partes a la cadena que
   sigue a @c{interactive}. Al hacer esto, la información se
   pasa a cada argumento en el mismo orden que se especifica en la lista
   @c{interactive}. En la cadena, cada parte está separada de la siguente
   parte por un @'{\n}, que significa nueva línea. Por ejemplo, a @'{p} puede
   continuar un @'{\n} y un @'{cZap to char: }. Esto hace que Emacs pase el
   valor del argumento prefijo (si lo hay) y el carácter.

#    In this case, the function definition looks like the following, where
#    @c{arg} and @c{char} are the symbols to which @c{interactive} binds the
#    prefix argument and the specified character:
   En este caso, la definición de función se parece a la siguiente, donde
   @c{arg} y @c{char} son los símbolos que @c{interactive} vincula al
   argumento prefijo y el caracter especificado:

#    ..src > elisp
#      (defun name-of-function (arg char)
#        "documentation…"
#        (interactive "p\ncZap to char: ")
#        body-of-function…)
#    < src..
   ..src > elisp
     (defun nombre-de-funcion (arg char)
       "documentacion…"
       (interactive "p\ncZap to char: ")
       cuerpo-de-funcion…)
   < src..

#    (The space after the colon in the prompt makes it look better when you are
#    prompted. See Section @l{#The Definition of @c{copy-to-buffer}}, for an
#    example.)
   (El espacio después de los dos puntos en el prompt hace que se vea mejor.
   Consulta la Seccion @l{#La Definición de @c{copy-to-buffer}}, para ver un
   ejemplo.)

#    When a function does not take arguments, @c{interactive} does not require
#    any. Such a function contains the simple expression @c{(interactive)}.
#    The @c{mark-whole-buffer} function is like this.
   Cuando una función no toma argumentos, @c{interactive} no requiere
   ninguno. Una función asi contiene unicamente la expresión
   @c{(interactive)}. La función @c{mark-whole-buffer} es asi.

#    Alternatively, if the special letter-codes are not right for your
#    application, you can pass your own arguments to @c{interactive} as a list.
   Alternativamente, si los códigos de letras especiales no son adecuados
   para tu aplicación, puedes pasar tus propios argumentos a
   @c{interactive} como una lista.

#    See Section @l{#The Definition of @c{append-to-buffer}}, for an example.
#    See Section @l{elisp.html#Using Interactive<>Using @c{Interactive}} in the
#    @e{The GNU Emacs Lisp Reference Manual}, for a more complete explanation
#    about this technique.
   Consulta la Seccion @l{#La Definición de @c{append-to-buffer}}, para ver un
   ejemplo. Consulta la Sección @l{elisp.html#Using Interactive<>Usando
   @c{interactive}} en @e(El Manual de GNU Emacs Lisp), para una explicación más
   completa sobre esta técnica.

# ** Install Code Permanently
** Instalar Código Permanentemente

#    When you install a function definition by evaluating it, it will stay
#    installed until you quit Emacs. The next time you start a new session of
#    Emacs, the function will not be installed unless you evaluate the function
#    definition again.
   Cuando instalas una definición de función evaluandola, permanecera instalada
   hasta que salgas de Emacs. La proxima vez que inicies una nueva sesión de
   Emacs, la función no sera instalada a menos que evalúes de nuevo la
   definición.

#    At some point, you may want to have code installed automatically whenever
#    you start a new session of Emacs. There are several ways of doing this:
   En algún momento, podrias necesitar que el código se instale
   automáticamente cada vez que inicies una nueva sesión de Emacs. Hay varias
   formas de hacer esto:

#    - If you have code that is just for yourself, you can put the code for the
#      function definition in your @f{.emacs} initialization file. When you
#      start Emacs, your @f{.emacs} file is automatically evaluated and all the
#      function definitions within it are installed. See Section @l{#Your
#      @f{.emacs} File}.
   - Si tienes código solo para tu personal, puedes poner el código de la
     definición de función en el fichero de inicialización @f{.emacs}. Cuando se
     inicia Emacs, el fichero @f{.emacs} se evalúa automáticamente y se instalan
     todas las definiciones de función que contiene. Consulta la Sección @l{#Tu
     Fichero @f{.emacs}}.

#    - Alternatively, you can put the function definitions that you want
#      installed in one or more files of their own and use the @c{load}
#      function to cause Emacs to evaluate and thereby install each of the
#      functions in the files. See Section @l{#Loading Files}.
   - Como Alternativa, puedes poner las definiciones de función en uno o más
     ficheros y usar la función @c{load} para hacer que Emacs evalue y con
     ello instale cada una de las funciones en los ficheros. Consulta la Seccion
     @l{#Cargando ficheros}.

#    - Thirdly, if you have code that your whole site will use, it is usual to
#      put it in a file called @f{site-init.el} that is loaded when Emacs is
#      built. This makes the code available to everyone who uses your machine.
#      (See the @f{INSTALL} file that is part of the Emacs distribution.)
   - En Tercer lugar, si tienes código que todo tu sitio va a utilizar, es
     normal ponerlo en un fichero llamado @f{site-init.el} que se carga
     cuando se construye Emacs. Esto hace que el código este disponible para
     todos los usuarios de tu máquina. (Mira el fichero @f{INSTALL} que forma
     parte de la distribución Emacs.)

#    Finally, if you have code that everyone who uses Emacs may want, you can
#    post it on a computer network or send a copy to the Free Software
#    Foundation.  (When you do this, please license the code and its
#    documentation under a license that permits other people to run, copy,
#    study, modify, and redistribute the code and which protects you from
#    having your work taken from you.)  If you send a copy of your code to the
#    Free Software Foundation, and properly protect yourself and others, it may
#    be included in the next release of Emacs. In large part, this is how
#    Emacs has grown over the past years, by donations.
   Finalmente, si tienes código que cualquier usuario de Emacs pueda querer,
   puedes publicarlo en una red de computadores o enviar una copia a la Free
   Software Foundation. (Al hacer esto, por favor licencia el código y su
   documentación bajo una licencia que permita a otras personas ejecutar,
   copiar, estudiar, modificar, y redistribuir el código y te proteja de quien
   tome tu trabajo.) Si envias una copia de tu código a la Free Software
   Foundation, y te proteges apropiadamente a ti mismo y a los demas, puede ser
   incluido en la siguiente version de Emacs. En gran parte, esta es la forma
   como ha crecido Emacs a través de los años, gracias a las de donaciones.

# ** @c{let}
** @c{let}

#    The @c{let} expression is a special form in Lisp that you will need to use
#    in most function definitions.
   La expresión @c{let} es una forma especial de Lisp que tendras que
   utilizar en la mayoría de las definiciones de función.

#    @c{let} is used to attach or bind a symbol to a value in such a way that
#    the Lisp interpreter will not confuse the variable with a variable of the
#    same name that is not part of the function.
   @c{let} se utiliza para unir o enlazar un símbolo a un valor de tal manera
   que el intérprete no confunda la variable con otra variable del mismo
   nombre que no forme parte de la función.

#    To understand why the @c{let} special form is necessary, consider the
#    situation in which you own a home that you generally refer to as ‘the
#    house’, as in the sentence, “The house needs painting.”  If you are
#    visiting a friend and your host refers to ‘the house’, he is likely to be
#    referring to @e{his} house, not yours, that is, to a different house.
   Para entender por qué la forma especial @c{let} es necesaria, considera la
   situación donde eres dueño de una casa que generalmente vinculas con ‘la
   casa’, como en la frase, “La casa necesita pintura”. Si visitas a un amigo
   y tu anfitrion hace referencia a ‘la casa’, es probable que se refiera a
   @e{su} casa, no a la tuya, es decir, a una casa diferente.

#    If your friend is referring to his house and you think he is referring to
#    your house, you may be in for some confusion. The same thing could happen
#    in Lisp if a variable that is used inside of one function has the same
#    name as a variable that is used inside of another function, and the two
#    are not intended to refer to the same value. The @c{let} special form
#    prevents this kind of confusion.
   Si tu amigo se refiere a su casa y tu crees que el se esta refiriendo a tu
   casa, puedes encontrarte en una situacion confusa. Lo mismo podría suceder en
   Lisp si una variable que se usa dentro de una función tiene el mismo nombre
   que una variable que se utiliza dentro de otra función, y no se pretende que
   ambas se refieran al mismo valor. La forma especial @c{let} permite evitar
   este tipo de confusión.

#    The @c{let} special form prevents confusion.  @c{let} creates a name for a
#    @:{local variable} that overshadows any use of the same name outside the
#    @c{let} expression. This is like understanding that whenever your host
#    refers to ‘the house’, he means his house, not yours.  (Symbols used in
#    argument lists work the same way. See Section @l{#The @c{defun} Special
#    Form}.)
   La forma especial @c{let} evita confusiones. @c{let} crea un nombre para
   una @:{variable local} que eclipsa cualquier uso del mismo nombre fuera de
   la expresión @c{let}. Esto es como entender que cuando tu anfitrion
   haga referencia a ‘la casa’, el quiere referirse a su casa, no la tuya. (Los símbolos
   usados en las listas de argumentos funcionan de la misma manera. Consulta la
   Sección @l{#La Forma Especial @c{defun}}.)

#    Local variables created by a @c{let} expression retain their value
#    @e{only} within the @c{let} expression itself (and within expressions
#    called within the @c{let} expression); the local variables have no effect
#    outside the @c{let} expression.
   Las variable locales creadas por una expresión @c{let} retienen su valor
   @e{solo} dentro de la expresión @c{let} (y dentro de las expresiones
   llamadas dentro de la expresión @c{let}); las variables locales no tiene
   efecto fuera de la expresión @c{let}.

#    Another way to think about @c{let} is that it is like a @c{setq} that is
#    temporary and local. The values set by @c{let} are automatically undone
#    when the @c{let} is finished. The setting only affects expressions that
#    are inside the bounds of the @c{let} expression. In computer science
#    jargon, we would say “the binding of a symbol is visible only in functions
#    called in the @c{let} form; in Emacs Lisp, scoping is dynamic, not
#    lexical.”
   Otra forma de persar sobre @c{let} es que es como un @c{setq} que es temporal
   y local. Los valores establecidos por @c{let} se deshacen automáticamente
   cuando @c{let} finaliza. La configuración solo afecta a las expresiones que
   se encuentran dentro de los limites de la expresión @c{let}. En la jerga
   informatica, diríamos que “la union de un simbolo solo es visible en las
   funciones llamadas en la forma @c{let}; en Emacs Lisp, el alcance es
   dinámico, no léxico.”

#    @c{let} can create more than one variable at once. Also, @c{let} gives
#    each variable it creates an initial value, either a value specified by
#    you, or @c{nil}.  (In the jargon, this is called ‘binding the variable to
#    the value’.)  After @c{let} has created and bound the variables, it
#    executes the code in the body of the @c{let}, and returns the value of the
#    last expression in the body, as the value of the whole @c{let} expression.
#    (‘Execute’ is a jargon term that means to evaluate a list; it comes from
#    the use of the word meaning ‘to give practical effect to’ (@q{Oxford
#    English Dictionary}). Since you evaluate an expression to perform an
#    action, ‘execute’ has evolved as a synonym to ‘evaluate’.)
   @c{let} puede crear más de una variable a la vez. Ademas, @c{let} da a cada
   variable que crea un valor inicial, ya sea un valor especificado por tí, o
   @c{nil}. (En la jerga, eso se llama ‘enlazar la variable al valor’.)  Después
   de que @c{let} ha creado y enlazado las variables, ejecuta el código en el
   cuerpo del @c{let} y devuelve el valor de la última expresión en el cuerpo,
   como el valor de toda la expresión @c{let}. (‘Ejecutar’ es un término tecnico
   que significa evaluar una lista; proviene del significando de la palabra
   ‘llevar a la practica’ (@e{Oxford English Dictionary}). Puesto que se evalua una
   expresión para realizar una acción, ‘ejecutar’ ha evolucionado como un
   sinónimo para ‘evaluar’.)

# *** The Parts of a @c{let} Expression
*** Partes de una expresión @c{let}

#     A @c{let} expression is a list of three parts. The first part is the
#     symbol @c{let}. The second part is a list, called a @:{varlist}, each
#     element of which is either a symbol by itself or a two-element list, the
#     first element of which is a symbol. The third part of the @c{let}
#     expression is the body of the @c{let}. The body usually consists of one
#     or more lists.
    Una expresión @c{let} es una lista de tres partes. La primer parte es el
    símbolo @c{let}. La segunda parte es una lista, llamada @:{varlist}
    @%i(lista de variables), cada uno de cuyos elementos es un símbolo por sí
    mismo o una lista de dos elementos, cuyo primer elemento es un símbolo. La
    tercer parte de la expresión @c{let} es el cuerpo de @c{let}. El cuerpo
    normalmente consiste de una o más listas.

#     A template for a @c{let} expression looks like this:
    Una plantilla de la expresión @c{let} se veria asi:

#     ..src > elisp
#       (let varlist body…)
#     < src..
    ..src > elisp
      (let varlist cuerpo…)
    < src..

#     The symbols in the varlist are the variables that are given initial
#     values by the @c{let} special form. Symbols by themselves are given the
#     initial value of @c{nil}; and each symbol that is the first element of a
#     two-element list is bound to the value that is returned when the Lisp
#     interpreter evaluates the second element.
    Los símbolos de la lista de varibles @%c(varlist) son las variables a las
    que la forma especial @c{let} da valores de inicio. A los símbolos por si
    mismos se les da el valor inicial @c{nil}; y cada símbolo que sea el primer
    elemento de una lista de dos elementos se vincula al valor que se devuelve
    cuando el interprete Lisp evalúa el segundo elemento.

#     Thus, a varlist might look like this: @c{(thread (needles 3))}. In this
#     case, in a @c{let} expression, Emacs binds the symbol @c{thread} to an
#     initial value of @c{nil}, and binds the symbol @c{needles} to an initial
#     value of 3.
    Por lo tanto, una varlist podria verse asi: @c{(hilo (agujas 3))}. En
    este caso, en una expresión @c{let}, Emacs une el símbolo @c{hilo} a
    un valor inicial de @c{nil}, y une el símbolo @c{agujas} a un valor inicial
    de 3.

#     When you write a @c{let} expression, what you do is put the appropriate
#     expressions in the slots of the @c{let} expression template.
    Cuando escribes una expresión @c{let}, lo que haces es poner las
    expresiones apropiadas en los espacios de la plantilla de la expresión
    @c{let}.

#     If the varlist is composed of two-element lists, as is often the case,
#     the template for the @c{let} expression looks like this:
    Si la varlist está compuesta de listas de 2 elementos, como suele ser el
    caso, la plantilla de la expresión @c{let} se ve asi:

#     ..src > elisp
#       (let ((variable value)
#             (variable value)
#             …)
#         body…)
#     < src..
    ..src > elisp
      (let ((variable valor)
            (variable valor)
            …)
        cuerpo…)
    < src..

# *** Sample @c{let} Expression
*** Ejemplo de Expresión @c{let}

#     The following expression creates and gives initial values to the two
#     variables @c{zebra} and @c{tiger}. The body of the @c{let} expression is
#     a list which calls the @c{message} function.
    La siguiente expresión crea y da valores iniciales a las dos variables
    @c{cebra} y @c{tigre}. El cuerpo de la expresión @c{let} es una lista que
    llama a la función @c{message}.

#     ..src > elisp
#       (let ((zebra 'stripes)
#             (tiger 'fierce))
#         (message "One kind of animal has %s and another is %s."
#                  zebra tiger))
#     < src..
    ..src > elisp
      (let ((cebra 'rayas)
            (tigre 'fiero))
        (message "Un tipo de animal tiene %s y otro es %s."
                 cebra tigre))
    < src..

#     Here, the varlist is @c{((zebra 'stripes) (tiger 'fierce))}.
    Aquí, la varlist es @c{((cebra 'rayas) (tigre 'fiero))}.

#     The two variables are @c{zebra} and @c{tiger}. Each variable is the
#     first element of a two-element list and each value is the second element
#     of its two-element list. In the varlist, Emacs binds the variable
#     @c{zebra} to the value @c{stripes}@n{8}, and binds the variable @c{tiger}
#     to the value @c{fierce}. In this example, both values are symbols
#     preceded by a quote. The values could just as well have been another
#     list or a string. The body of the @c{let} follows after the list holding
#     the variables. In this example, the body is a list that uses the
#     @c{message} function to print a string in the echo area.
    Las dos variables son @c{cebra} y @c{tigre}. Cada variable es el primer
    elemento de una lista de dos elementos y cada valor es el segundo
    elemento de su lista de dos elementos. En la varlist, Emacs une la
    variable @c{cebra} al valor @c{rayas}@n{8}, y la variable @c{tigre}
    al valor @c{fiero}. En este ejemplo, ambos valores son símbolos
    precedidos por una cita. Los valores podrían muy bien haber sido otra
    lista o una cadena. El cuerpo de @c{let} sigue después de la lista que
    contiene las variables. En este ejemplo, el cuerpo es una lista que usa
    la función @c{message} para imprimir una cadena en el área de eco.

#     You may evaluate the example in the usual fashion, by placing the cursor
#     after the last parenthesis and typing @k{C-x C-e}. When you do this, the
#     following will appear in the echo area:
    Puedes evaluar el ejemplo de la forma habitual, colocando el cursor después
    del último paréntesis y presionando @k{C-x C-e}. Al hacer esto, aparecerá lo
    siguiente en el área de eco:

#     ..src > elisp
#       "One kind of animal has stripes and another is fierce."
#     < src..
    ..src > elisp
      "Un tipo de animal tiene rayas y otro es fiero."
    < src..

#     As we have seen before, the @c{message} function prints its first
#     argument, except for @'{%s}. In this example, the value of the variable
#     @c{zebra} is printed at the location of the first @'{%s} and the value of
#     the variable @c{tiger} is printed at the location of the second @'{%s}.
    Como hemos visto anteriormente, la función @c{message} imprime su primer
    argumento, excepto @'{%s}. En este ejemplo, el valor de la variable
    @c{cebra} se imprime en la ubicacion del primer @'{%s} y el valor de la
    variable @c{tigre} se imprime en la ubicacion del segundo @'{%s}.

# *** Uninitialized Variables in a @c{let} Statement
*** Variables sin inicializar en un sentencia @c{let}

#     If you do not bind the variables in a @c{let} statement to specific
#     initial values, they will automatically be bound to an initial value of
#     @c{nil}, as in the following expression:
    Si no se unen las variables en una sentencia @c{let} con valores
    de inicio específicos, automáticamente seran enlazados a un valor de inicio
    @c{nil}, como en la siguiente expresión:

#     ..src > elisp
#       (let ((birch 3)
#             pine
#             fir
#             (oak 'some))
#         (message "Here are %d variables with %s, %s, and %s value."
#                  birch pine fir oak))
#     < src..
    ..src > elisp
      (let ((abedul 3)
            pino
            abeto
            (roble 'algunos))
        (message "Aquí están %d variables con %s, %s, y el valor %s."
                 abedul pino abeto roble))
    < src..

#     Here, the varlist is @c{((birch 3) pine fir (oak 'some))}.
    Aquí, la varlist es @c{((abedul 3) pino abeto (roble 'algunos))}.

#     If you evaluate this expression in the usual way, the following will
#     appear in your echo area:
    Si evalúas esta expresión de la forma habitual, aparecerá lo siguiente en
    el área de eco:

#     ..example >
#       "Here are 3 variables with nil, nil, and some value."
#     < example..
    ..example >
      "Aquí están 3 variables con nil, nil, y el valor algunos."
    < example..

#     In this example, Emacs binds the symbol @c{birch} to the number 3, binds
#     the symbols @c{pine} and @c{fir} to @c{nil}, and binds the symbol @c{oak}
#     to the value @c{some}.
    En este ejemplo, Emacs une el símbolo @c{abedul} al número 3, une los
    símbolos @c{pino} y @c{abeto} a @c{nil}, y el símbolo @c{roble} al
    valor @c{algunos}.

#     Note that in the first part of the @c{let}, the variables @c{pine} and
#     @c{fir} stand alone as atoms that are not surrounded by parentheses; this
#     is because they are being bound to @c{nil}, the empty list. But @c{oak}
#     is bound to @c{some} and so is a part of the list @c{(oak 'some)}.
#     Similarly, @c{birch} is bound to the number 3 and so is in a list with
#     that number.  (Since a number evaluates to itself, the number does not
#     need to be quoted. Also, the number is printed in the message using a
#     @'c{%d} rather than a @'c{%s}.)  The four variables as a group are put into
#     a list to delimit them from the body of the @c{let}.
    Observa que en la primer parte de @c{let}, las variables @c{pino} y
    @c{abeto} son unicamente átomos que no están rodeados por paréntesis;
    esto es porque estan siendo ligados a @c{nil}, la lista vacía. Pero
    @c{roble} su une a @c{algunos} por que es parte de la lista @c{(roble
    'algunos)}. De manera similar, @c{abedul} se une al número 3 en una lista
    con este número. (Ya que un número se evalúa a sí mismo, no es necesario
    citar el numero. Ademas, el número se imprime en el mensaje
    utilizando un @'c{%d} en lugar de un @'c{%s}.) Las cuatro variables como
    grupo se ponen en una lista para delimitarlas del cuerpo de @c{let}.

# ** The @c{if} Special Form
** La forma especial @c{if}

#    A third special form, in addition to @c{defun} and @c{let}, is the
#    conditional @c{if}. This form is used to instruct the computer to make
#    decisions. You can write function definitions without using @c{if}, but
#    it is used often enough, and is important enough, to be included here. It
#    is used, for example, in the code for the function
#    @c{beginning-of-buffer}.
   Además de @c{let} y @c{defun}, esta la forma especial condicional @c{if}.
   Esta forma se utiliza para indicar al ordenador que tome decisiones.
   Puedes escribir definiciones de función sin necesidad de utilizar @c{if},
   pero se usa con bastante frecuencia, y es lo suficientemente importante
   como para incluirla aquí. Se utiliza, por ejemplo, en el código de la
   función @c{beginning-of-buffer}.

#    The basic idea behind an @c{if}, is that “@e{if} a test is true, @e{then}
#    an expression is evaluated.”  If the test is not true, the expression is
#    not evaluated. For example, you might make a decision such as, “if it is
#    warm and sunny, then go to the beach!”
   La idea básica detras de @c{if}, es que “@e{si} @%i(if) una prueba es verdadera
   @e{entonces} @%i(then) se evalua la expresión”. Si la prueba no es verdadera, la
   expresión no se evalua. Por ejemplo, podrías tomar una decisión como, “si
   hace sol y calor, entonces ve a la playa!”

#    An @c{if} expression written in Lisp does not use the word ‘then’; the
#    test and the action are the second and third elements of the list whose
#    first element is @c{if}. Nonetheless, the test part of an @c{if}
#    expression is often called the @:{if-part} and the second argument is
#    often called the @:{then-part}.
   Al escribir una expresión @c{if} en Lisp no se utiliza la palabra ‘entonces’;
   la prueba y la acción son los elementos segundo y tercero de la lista cuyo
   primer elemento es @c{if}. No obstante, la parte de la prueba en una
   expresión @c{if} a menudo se llamada @:{parte-si} @%i(if-part) y el segundo
   argumento a menudo se llamada @:{parte-entonces} @%i(then-part).

#    Also, when an @c{if} expression is written, the true-or-false-test is
#    usually written on the same line as the symbol @c{if}, but the action to
#    carry out if the test is true, the “then-part”, is written on the second
#    and subsequent lines. This makes the @c{if} expression easier to read.
   Ademas, cuando se escribe una expresión @c{if}, la prueba-verdadero-o-falso
   normalmente se escribe en la misma línea que el símbolo @c{if}, pero la
   acción a llevar a cabo si la prueba es verdadera, “parte-entonces”, se
   escribe en la segunda y suguientes líneas. Esto hace que la expresión @c{if}
   sea mas fácil de leer.

#    ..src > elisp
#      (if true-or-false-test
#          action-to-carry-out-if-test-is-true)
#    < src..
   ..src > elisp
     (if prueba-verdadero-o-falso
         accion-a-realizar-si-la-prueba-es-verdadera)
   < src..

#    The true-or-false-test will be an expression that is evaluated by the Lisp
#    interpreter.
   La prueba-verdadero-o-falso es una expresión que evalua el intérprete
   Lisp.

#    Here is an example that you can evaluate in the usual manner. The test is
#    whether the number 5 is greater than the number 4. Since it is, the
#    message @'{5 is greater than 4!} will be printed.
   Aquí hay un ejemplo que puedes evaluar. La prueba consiste en si el número
   5 es mayor que el número 4. Puesto que es asi, se imprime el mensaje @'{¡5 es
   mayor que 4!}.

#    ..src > elisp
#      (if (> 5 4)                             ; if-part
#          (message "5 is greater than 4!"))   ; then-part
#    < src..
   ..src > elisp
     (if (> 5 4)                           ; parte-si
         (message "¡5 es mayor que 4!"))   ; parte-entonces
   < src..

#    (The function @c{>} tests whether its first argument is greater than its
#    second argument and returns true if it is.)
   (La función @c{>} comprueba si su primer argumento es mayor que su segundo
   argumento y devuelve verdadero si lo es.)

#    Of course, in actual use, the test in an @c{if} expression will not be
#    fixed for all time as it is by the expression @c{(> 5 4)}. Instead, at
#    least one of the variables used in the test will be bound to a value that
#    is not known ahead of time.  (If the value were known ahead of time, we
#    would not need to run the test!)
   Por supuesto, en un caso real, la prueba en una expresión @c{if} no será
   fija eternamente, como en la expresión @c{(> 5 4)}. En su lugar, al menos
   una de las variables utilizadas en la prueba estara unida a un valor de
   antemano desconocido. (Si el valor se conociera de antemano, ¡no necesitariamos
   realizar la prueba!)

#    For example, the value may be bound to an argument of a function
#    definition. In the following function definition, the character of the
#    animal is a value that is passed to the function. If the value bound to
#    @c{characteristic} is @c{fierce}, then the message, @'{It's a tiger!} will
#    be printed; otherwise, @c{nil} will be returned.
   Por ejemplo, el valor puede estar unido a un argumento de una definición
   de función. En la siguiente definición de función, el tipo de animal es un
   valor que se pasa a la función. Si el valor unido a @c{caracteristica} es
   @c{fiero}, entonces se imprime el mensaje, @'{¡Es un tigre!}; de otro
   modo, se devolvera @c{nil}.

#    ..src > elisp
#      (defun type-of-animal (characteristic)
#        "Print message in echo area depending on CHARACTERISTIC.
#      If the CHARACTERISTIC is the symbol ‘fierce’,
#      then warn of a tiger."
#        (if (equal characteristic 'fierce)
#            (message "It's a tiger!")))
#    < src..
   ..src > elisp
     (defun tipo-de-animal (caracteristica)
       "Imprime el mensaje en el área de eco dependiendo de CARACTERISTICA.
     Si la CARACTERISTICA es el símbolo ‘fiero’,
     entonces advierte que es un tigre."
       (if (equal caracteristica 'fiero)
           (message "¡Es un tigre!")))
   < src..

#    If you are reading this inside of GNU Emacs, you can evaluate the function
#    definition in the usual way to install it in Emacs, and then you can
#    evaluate the following two expressions to see the results:
   Si estás leyendo esto dentro de GNU Emacs, puedes evaluar la definición de
   función de la forma habitual para instalarla en Emacs, y luego puedes
   evaluar las siguientes dos expresiones para ver los resultados:

#    ..src > elisp
   ..src > elisp
#      (type-of-animal 'fierce)
     (tipo-de-animal 'fiero)

#      (type-of-animal 'zebra)
     (tipo-de-animal 'cebra)
#    < src..
   < src..

#    When you evaluate @c{(type-of-animal 'fierce)}, you will see the following
#    message printed in the echo area: @c{"It's a tiger!"}; and when you
#    evaluate @c{(type-of-animal 'zebra)} you will see @c{nil} printed in the
#    echo area.
   Al evaluar @c{(tipo-de-animal 'fiero)}, veras el siguiente mensaje impreso
   en el área de eco: @c{"¡Es un tigre!"}; y cuando se evalúa @c{(tipo-de-animal
   'cebra)} verás @c{nil} impreso en el área de eco.

# *** The @c{type-of-animal} Function in Detail
*** La función @c{tipo-de-animal} en detalle

#     Let's look at the @c{type-of-animal} function in detail.
    Veamos en detalle la función @c{tipo-de-animal}.

#     The function definition for @c{type-of-animal} was written by filling the
#     slots of two templates, one for a function definition as a whole, and a
#     second for an @c{if} expression.
    La definición de función @c{tipo-de-animal} se escribio llenando los
    espacios de dos plantillas, una para la definición de función como
    un todo, y otra para una expresión @c{if}.

#     The template for every function that is not interactive is:
    La plantilla para toda función no interactiva es:

#     ..src > elisp
#       (defun name-of-function (argument-list)
#         "documentation…"
#         body…)
#     < src..
    ..src > elisp
      (defun nombre-de-funcion (lista-de-argumentos)
        "documentacion…"
        cuerpo…)
    < src..

#     The parts of the function that match this template look like this:
    Las partes de la función que coinciden con esta plantilla tienen el siguiente aspecto:

#     ..src > elisp
#       (defun type-of-animal (characteristic)
#         "Print message in echo area depending on CHARACTERISTIC.
#       If the CHARACTERISTIC is the symbol ‘fierce’,
#       then warn of a tiger."
#         body: the if expression)
#     < src..
    ..src > elisp
      (defun tipo-de-animal (caracteristica)
        "Imprime el mensaje en el área de eco dependiendo de CARACTERISTICA.
      Si la CARACTERISTICA es el símbolo ‘fiero’,
      entonces advierte que es un tigre."
        cuerpo: la expresion if)
    < src..

#     The name of function is @c{type-of-animal}; it is passed the value of one
#     argument. The argument list is followed by a multi-line documentation
#     string. The documentation string is included in the example because it
#     is a good habit to write documentation string for every function
#     definition. The body of the function definition consists of the @c{if}
#     expression.
    El nombre de función es @c{tipo-de-animal}; se le pasa el valor de un
    argumento. A la lista de argumentos le sigue una cadena de documentación
    multilínea. La cadena de documentación se incluiye en el ejemplo porque
    es un buen hábito escribir un cadena de documentación para cada
    definición de función. El cuerpo de la definición de función consiste en
    la expresión @c{if}.

#     The template for an @c{if} expression looks like this:
    La plantilla de una expresión @c{if} se ve así:

#     ..src > elisp
#       (if true-or-false-test
#           action-to-carry-out-if-the-test-returns-true)
#     < src..
    ..src > elisp
      (if prueba-verdadero-o-falso
          accion-a-realizar-si-la-prueba-devuelve-verdadero)
    < src..

#     In the @c{type-of-animal} function, the code for the @c{if} looks like
#     this:
    En la función @c{tipo-de-animal}, el código para el @c{if} se ve así:

#     ..src > elisp
#       (if (equal characteristic 'fierce)
#           (message "It's a tiger!")))
#     < src..
    ..src > elisp
      (if (equal caracteristica 'fiero)
          (message "¡Es un tigre!")))
    < src..

#     Here, the true-or-false-test is the expression:
    Aquí, está la expresión prueba-verdadero-o-falso

#     ..src > elisp
#       (equal characteristic 'fierce)
#     < src..
    ..src > elisp
      (equal caracteristica 'fiero)
    < src..

#     In Lisp, @c{equal} is a function that determines whether its first
#     argument is equal to its second argument. The second argument is the
#     quoted symbol @c{'fierce} and the first argument is the value of the
#     symbol @c{characteristic}––in other words, the argument passed to this
#     function.
    En Lisp, @c{equal} es una función que determina si su primer argumento es
    igual al segundo. El segundo argumento es el símbolo citado @c{'fiero} y el
    primer argumento es el valor del símbolo @c{característica}––en otras
    palabras, el argumento pasado a esta función.

#     In the first exercise of @c{type-of-animal}, the argument @c{fierce} is
#     passed to @c{type-of-animal}. Since @c{fierce} is equal to @c{fierce},
#     the expression, @c{(equal characteristic 'fierce)}, returns a value of
#     true. When this happens, the @c{if} evaluates the second argument or
#     then-part of the @c{if}: @c{(message "It's tiger!")}.
    En la primer prueba de @c{tipo-de-animal}, el argumento @c{fiero} se pasa
    a @c{tipo-de-animal}. Ya que @c{fiero} es igual a @c{fiero}, la
    expresión, @c{(equal caracteristica 'fiero)}, devuelve el valor
    verdadero. Cuando esto sucede, @c{if} evalúa el segundo argumento o la
    parte-entonces del @c{if}: @c{(message "¡Es un tigre!")}.

#     On the other hand, in the second exercise of @c{type-of-animal}, the
#     argument @c{zebra} is passed to @c{type-of-animal}.  @c{zebra} is not
#     equal to @c{fierce}, so the then-part is not evaluated and @c{nil} is
#     returned by the @c{if} expression.
    Por otro lado, en la segunda prueba de @c{tipo-de-animal}, se pasa el
    argumento @c{cebra} a @c{tipo-de-animal}. @c{cebra} no es igual a @c{fiero},
    por lo que la parte-entonces no se evalua y la expresión @c{if} devuelve
    @c{nil}).

# ** If––then––else Expressions
** Expresiones if–then–else

#    An @c{if} expression may have an optional third argument, called the
#    @:{else-part}, for the case when the true-or-false-test returns false.
#    When this happens, the second argument or then-part of the overall @c{if}
#    expression is @e{not} evaluated, but the third or else-part @e{is}
#    evaluated. You might think of this as the cloudy day alternative for the
#    decision “if it is warm and sunny, then go to the beach, else read a
#    book!”.
   Una expresión @c{if} puede tener un tercer argumento opcional, llamado
   @:(parte-de-otro-modo) @%i{else-part}, en caso de que la
   prueba-verdadero-o-falso devuelva falso. Cuando esto sucede, el segundo
   argumento o parte-entonces de la expresión @c{if} global @e{no} se evalúa, pero
   el tercer argumento o parte-de-otro-modo @e{se} evalúa. Podrías pensar en
   esto como la alternativa del día nublado para la decisión “si es cálido y
   soleado, entonces ir a la playa!, de otro modo leer un libro!”

#    The word “else” is not written in the Lisp code; the else-part of an
#    @c{if} expression comes after the then-part. In the written Lisp, the
#    else-part is usually written to start on a line of its own and is indented
#    less than the then-part:
   La palabra “else” @%i(de otro modo) no se escribe en el código Lisp; la
   parte-de-otro-modo de una expresión @c{if} viene después de la
   parte-entonces. En Lisp, la parte-de-otro-modo suele escribirse al inicio
   de una nueva linea y tiene menos indentacion que la parte-entonces:

#    ..src > elisp
#      (if true-or-false-test
#          action-to-carry-out-if-the-test-returns-true
#        action-to-carry-out-if-the-test-returns-false)
#    < src..
   ..src > elisp
     (if prueba-verdadero-o-falso
         accion-a-realizar-si-la-prueba-devuelve-verdadero
       accion-a-realizar-si-la-prueba-devuelve-falso)
   < src..

#    For example, the following @c{if} expression prints the message @'{4 is
#    not greater than 5!} when you evaluate it in the usual way:
   Por ejemplo, evaluar la siguiente expresión @c{if} imprime el mensaje @'{¡4 no es
   mayor que 5!}:

#    ..src > elisp
#      (if (> 4 5)                               ; if-part
#          (message "4 falsely greater than 5!") ; then-part
#        (message "4 is not greater than 5!"))   ; else-part
#    < src..
   ..src > elisp
     (if (> 4 5)                                   ; parte-if
         (message "¡4 falsamente es mayor que 5!") ; parte-then
       (message "¡4 no es mayor que 5!"))          ; parte-else
   < src..

#    Note that the different levels of indentation make it easy to distinguish
#    the then-part from the else-part.  (GNU Emacs has several commands that
#    automatically indent @c{if} expressions correctly. See Section @l{#GNU
#    Emacs Helps You Type Lists}.)
   Observa que los diferentes niveles de indentación hacen fácil distinguir la
   parte-entonces (por brevedad, y mezclando ingles con español, apartir de
   ahora @%i(parte-then)) de la parte-de-otro-modo (por brevedad, y mezclando
   ingles con español, apartir de ahora @%i(parte-else)). (GNU Emacs tiene
   varios comandos que indentan expresiones @c{if} automáticamente. Consulta la
   Seccion @l{#GNU Emacs te ayuda a escribir listas}.)

#    We can extend the @c{type-of-animal} function to include an else-part by
#    simply incorporating an additional part to the @c{if} expression.
   Podemos ampliar la función @c{tipo-de-animal} para incluir una parte-else
   simplemente incorporando una parte adicional a la expresión @c{if}.

#    You can see the consequences of doing this if you evaluate the following
#    version of the @c{type-of-animal} function definition to install it and
#    then evaluate the two subsequent expressions to pass different arguments
#    to the function.
   Puedes ver las consecuencias de hacer esto si evalúas la siguiente versión de
   la función @c{tipo-de-animal} y luego evaluas las dos expresiones siguientes
   que pasan argumentos diferentes a la función.

#    ..src > elisp
   ..src > elisp
#      (defun type-of-animal (characteristic)  ; Second version.
#        "Print message in echo area depending on CHARACTERISTIC.
#      If the CHARACTERISTIC is the symbol ‘fierce’,
#      then warn of a tiger;
#      else say it's not fierce."
#        (if (equal characteristic 'fierce)
#            (message "It's a tiger!")
#          (message "It's not fierce!")))
     (defun tipo-de-animal (caracteristica)
       "Imprime un mensaje en el área de eco dependiendo de la CARACTERISTICA.
     Si la CARACTERISTICA es el símbolo ‘fiero’,
     entonces advierte que es un tigre.
     de otro modo dice que no es fiero"
       (if (equal caracteristica 'fiero)
           (message "¡Es un tigre!")
         (message "!No es feroz!")))

#      (type-of-animal 'fierce)
     (tipo-de-animal 'fiero)

#      (type-of-animal 'zebra)
     (tipo-de-animal 'cebra)
#    < src..
   < src..

#    When you evaluate @c{(type-of-animal 'fierce)}, you will see the following
#    message printed in the echo area: @c{"It's a tiger!"}; but when you
#    evaluate @c{(type-of-animal 'zebra)}, you will see @c{"It's not fierce!"}.
   Cuando evalues @c{(tipo-de-animal 'fiero)}, verás el siguiente mensaje en el
   área de eco: @c{"¡Es un tigre!"}; cuando evalues @c{(tipo-de-animal
   'cebra)}, verás @c{"¡No es feroz!"}.

#    (Of course, if the @c{characteristic} were @c{ferocious}, the message
#    @c{"It's not fierce!"} would be printed; and it would be misleading!  When
#    you write code, you need to take into account the possibility that some
#    such argument will be tested by the @c{if} and write your program
#    accordingly.)
   (Por supuesto, si @c{característica} fuera @c{muy-feroz}, se imprimiria el
   mensaje @c{"¡No es feroz!"}; ¡y sería un error!  Cuando escribas código,
   debes tener en cuenta la posibilidad de que algun argumento como este
   sea probado por @c{if} y acorde a ello escribir tu programa.

# ** Truth and Falsehood in Emacs Lisp
** Verdad y Falsedad en Emacs Lisp

#    There is an important aspect to the truth test in an @c{if} expression.
#    So far, we have spoken of ‘true’ and ‘false’ as values of predicates as if
#    they were new kinds of Emacs Lisp objects. In fact, ‘false’ is just our
#    old friend @c{nil}. Anything else––anything at all––is ‘true’.
   Hay un aspecto importante para probar la verdad en una expresión
   @c{if}. Hasta ahora, hemos hablado de ‘verdadero’ y ‘falso’ como valores
   de predicados como si fueran nuevos tipos de objetos Emacs Lisp. De hecho,
   solo nuestro viejo amigo @c{nil} es ‘falso’. Cualquier otra
   cosa––cualquiera en absoluto––es ‘verdadero’.

#    The expression that tests for truth is interpreted as @:{true} if the
#    result of evaluating it is a value that is not @c{nil}. In other words,
#    the result of the test is considered true if the value returned is a
#    number such as 47, a string such as @c{"hello"}, or a symbol (other than
#    @c{nil}) such as @c{flowers}, or a list (so long as it is not empty), or
#    even a buffer!
   La expresión que prueba si algo es verdadero se interpreta como @:{true}
   @%i(verdadero) si el resultado de la evaluacion es no @c{nil}. En otras
   palabras, el resultado de la prueba se considera verdadero si el valor
   devuelto es un número como 47, una cadena como @c{"hola"}, o un símbolo
   (distinto de @c{nil}) como @c{flores}, o una lista (siempre y cuando no
   este vacía) o incluso ¡un búfer!

#    Before illustrating a test for truth, we need an explanation of @c{nil}.
   Antes de ilustrar una prueba para verdadero, necesitamos una explicación
   de @c{nil}.

#    In Emacs Lisp, the symbol @c{nil} has two meanings. First, it means the
#    empty list. Second, it means false and is the value returned when a
#    true-or-false-test tests false.  @c{nil} can be written as an empty list,
#    @c{()}, or as @c{nil}. As far as the Lisp interpreter is concerned,
#    @c{()} and @c{nil} are the same. Humans, however, tend to use @c{nil} for
#    false and @c{()} for the empty list.
   En Emacs Lisp, el símbolo @c{nil} tiene dos significados. En primer lugar,
   significa que la lista está vacía. En segundo lugar, significa falso y es
   el valor devuelto cuando una prueba-verdadero-o-falso obtiene falso.
   @c{nil} puede escribirse como una lista vacia, @c[()], o como @c(nil). En
   lo referente al interprete Lisp @c[()] y @c(nil) son lo mismo. Los
   humanos, sin embargo, tienden a usar @c{nil} para falso y @c{()} para
   lista vacía.

#    In Emacs Lisp, any value that is not @c{nil}––is not the empty list––is
#    considered true. This means that if an evaluation returns something that
#    is not an empty list, an @c{if} expression will test true. For example,
#    if a number is put in the slot for the test, it will be evaluated and will
#    return itself, since that is what numbers do when evaluated. In this
#    conditional, the @c{if} expression will test true. The expression tests
#    false only when @c{nil}, an empty list, is returned by evaluating the
#    expression.
   En Emacs Lisp, cualquier valor que no sea @c{nil}––si no es una lista
   vacía––se considera verdadero. Esto significa que si una evaluación devuelve
   algo que no es una lista vacía, una expresión @c{if} probara ser
   verdadera. Por ejemplo, si un número se coloca en el lugar de la prueba, se
   evaluara y devolverá su valor, ya que eso es lo que hacen los números cuando
   se evalúan. En esta condicion, la expresión @c{if} pasara su prueba como
   verdadero. La expresión pasara su prueba como falsa solo cuando @c{nil}, o
   una lista vacía, son devueltas al evaluar la expresión.

#    You can see this by evaluating the two expressions in the following
#    examples.
   Puedes ver esto evaluando las dos expresiones en los ejemplos siguientes.

#    In the first example, the number 4 is evaluated as the test in the @c{if}
#    expression and returns itself; consequently, the then-part of the
#    expression is evaluated and returned: @'{true} appears in the echo area.
#    In the second example, the @c{nil} indicates false; consequently, the
#    else-part of the expression is evaluated and returned: @'{false} appears
#    in the echo area.
   En el primer ejemplo, el número 4 se evalua como la prueba en la expresión
   @c{if} y se devuelve a si mismo; en consecuencia, se evalua y devuelve
   la parte-then de la expresión: aparece @'{verdadero} en el área de eco. En el
   segundo ejemplo, @c{nil} indica falso; en consecuencia, se evalua y
   devuelve la parte-else de la expresión: aparece @'{falso} en el área de eco.

#    ..src > elisp
   ..src > elisp
#      (if 4
#          'true
#        'false)
     (if 4
         'verdadero
       'falso)

#      (if nil
#          'true
#        'false)
     (if nil
         'verdadero
       'falso)
#    < src..
   < src..

#    Incidentally, if some other useful value is not available for a test that
#    returns true, then the Lisp interpreter will return the symbol @c{t} for
#    true. For example, the expression @c{(> 5 4)} returns @c{t} when
#    evaluated, as you can see by evaluating it in the usual way:
   Por cierto, si algún otro valor de utilidad no está disponible para una prueba
   que devuelve verdadero, entonces el intérprete Lisp devolvera el símbolo
   @c{t} para verdadero. Por ejemplo, la expresión @c{(> 5 4)} devuelve @c{t}
   cuando se evalúa, como puedes comprobar si evaluas:

#    ..src > elisp
#      (> 5 4)
#    < src..
   ..src > elisp
     (> 5 4)
   < src..

#    On the other hand, this function returns @c{nil} if the test is false.
   Por otra parte, esta función devuelve @c{nil} si la prueba es falsa.

#    ..src > elisp
#      (> 4 5)
#    < src..
   ..src > elisp
     (> 4 5)
   < src..

# ** @c{save-excursion}
** @c{save-excursion}

#    The @c{save-excursion} function is the fourth and final special form that
#    we will discuss in this chapter.
   La función @c{save-excursion} es la cuarta y última forma especial que
   discutiremos en este capítulo.

#    In Emacs Lisp programs used for editing, the @c{save-excursion} function
#    is very common. It saves the location of point and mark, executes the
#    body of the function, and then restores point and mark to their previous
#    positions if their locations were changed. Its primary purpose is to keep
#    the user from being surprised and disturbed by unexpected movement of
#    point or mark.
   En los programas Emacs Lisp utilizados para la edición, la función
   @c{save-excursion} es muy común. Guarda la posición del punto y marca,
   ejecuta el cuerpo de la función, y luego restaura el punto y marca a sus
   posiciones previas si sus posiciones fueron cambiadas. Su proposito
   principal es impedir que el usuario se sorprenda y perturbe por el
   movimiento inesperado del punto o marca.

#    Before discussing @c{save-excursion}, however, it may be useful first to
#    review what point and mark are in GNU Emacs.  @:{Point} is the current
#    location of the cursor. Wherever the cursor is, that is point. More
#    precisely, on terminals where the cursor appears to be on top of a
#    character, point is immediately before the character. In Emacs Lisp,
#    point is an integer. The first character in a buffer is number one, the
#    second is number two, and so on. The function @c{point} returns the
#    current position of the cursor as a number. Each buffer has its own value
#    for point.
   Sin embargo, antes de hablar de @c{save-excursion}, puede ser útil examinar
   primero que son el punto y la marca en GNU Emacs. @:{Punto} es la posición
   actual del cursor. Donde sea que se encuentre el cursor, estara el punto. De
   forma más precisa, en los terminales donde el cursor aparece sobre un
   carácter, el punto se encuentra inmediatamente antes del carácter. En Emacs Lisp, el
   punto es un numero entero. El primer carácter en un búfer es el número uno,
   el segundo es el número dos, y así sucesivamente. La función @c{point}
   devuelve la posición actual del cursor como un número. Cada búfer tiene su
   propio valor para el punto.

#    The @:{mark} is another position in the buffer; its value can be set
#    with a command such as @k{C-SPC} @%c(set-mark-command). If a mark has
#    been set, you can use the command @k{C-x C-x}
#    @%c(exchange-point-and-mark) to cause the cursor to jump to the mark
#    and set the mark to be the previous position of point. In addition, if
#    you set another mark, the position of the previous mark is saved in the
#    mark ring. Many mark positions can be saved this way. You can jump the
#    cursor to a saved mark by typing @k{C-u C-SPC} one or more times.
   La @:{marca} es otra posición en el búfer; su valor se puede establecer con
   un comando como @k{C-SPC} @%c(set-mark-command). Si se ha establecido una
   marca, puedes utilizar el comando @k{C-x C-x} @%c(exchange-point-and-mark)
   para hacer que el cursor salte a la marca y establecer la marca como la
   posición anterior del punto. Además, si se establece otra marca, la posición
   de la marca anterior se guarda en el anillo de marcas. Muchas posiciones de
   marca se pueden guardar de esta manera. Se puede mover el cursor a una marca
   guardada presionando @k{C-u C-SPC} una o más veces.

#    The part of the buffer between point and mark is called @:{the region}.
#    Numerous commands work on the region, including @c{center-region},
#    @c{count-lines-region}, @c{kill-region}, and @c{print-region}.
   La parte del búfer entre el punto y la marca se denomina @:{la región}.
   Numerosos comandos trabajan en la región, incluyendo @c{center-region},
   @c{count-lines-region}, @c{kill-region} y @c{print-region}.

#    The @c{save-excursion} special form saves the locations of point and mark
#    and restores those positions after the code within the body of the special
#    form is evaluated by the Lisp interpreter. Thus, if point were in the
#    beginning of a piece of text and some code moved point to the end of the
#    buffer, the @c{save-excursion} would put point back to where it was
#    before, after the expressions in the body of the function were evaluated.
   La forma especial @c{save-excursion} guarda las ubicaciones del punto y la
   marca y restaura estas posiciones después de que el interprete Lisp evalua el
   código dentro del cuerpo de la forma especial. De este modo, si el punto
   se encontraba al inicio de un texto y algún código moviera el
   punto al final del búfer, @c{save-excursion} volvera a poner el punto
   donde estaba antes, luego que las expresiones en el cuerpo de la funcion
   fueran evaluadas.

#    In Emacs, a function frequently moves point as part of its internal
#    workings even though a user would not expect this. For example,
#    @c{count-lines-region} moves point. To prevent the user from being
#    bothered by jumps that are both unexpected and (from the user's point of
#    view) unnecessary, @c{save-excursion} is often used to keep point and mark
#    in the location expected by the user. The use of @c{save-excursion} is
#    good housekeeping.
   En Emacs, una función se mueve con frecuencia de punto a otro como parte de
   su funcionamiento interno, aunque el usuario no lo espere. Por
   ejemplo, @c{count-lines-region} mueve el punto. Para evitar que el usuario
   sea molestado por saltos inesperados y (desde el punto de vista del usuario)
   innecesarios, @c{save-excursion} se utiliza a menudo para conservar el punto
   y la marca en la posición esperada por el usuario. El uso de
   @c{save-excursion} es bueno para mantener el orden.

#    To make sure the house stays clean, @c{save-excursion} restores the values
#    of point and mark even if something goes wrong in the code inside of it
#    (or, to be more precise and to use the proper jargon, “in case of abnormal
#    exit”). This feature is very helpful.
   Para asegurarse que la casa se mantiene limpia, @c{save-excursion}
   restaura los valores del punto y la marca incluso si algo va mal con el
   código en su cuerpo (o, para ser más preciso y usar el lenguaje tecnico
   apropiado, “en caso de salida anormal”). Esta caracteristica es muy útil.

#    In addition to recording the values of point and mark, @c{save-excursion}
#    keeps track of the current buffer, and restores it, too. This means you
#    can write code that will change the buffer and have @c{save-excursion}
#    switch you back to the original buffer. This is how @c{save-excursion} is
#    used in @c{append-to-buffer}.  (See Section @l{#The Definition of
#    @c{append-to-buffer}}.)
   Además de registrar los valores del punto y marca, @c{save-excursion}
   mantiene un registro del buffer actual, y tambien lo restaura. Esto significa que
   puedes escribir código que cambie de bufer y @c{save-excursion} lo devuelva
   al bufer original. Asi es como se utiliza @c{save-excursion} en
   @c{append-to-buffer}.  (Consulta la Seccion @l{#La Definición de
   @c{append-to-buffer}}.)

# *** Template for a @c{save-excursion} Expression
*** Plantilla para una Expresión @c{save-excursion}

#     The template for code using @c{save-excursion} is simple:
    La plantilla de código usando @c{save-excursion} es simple:

#     ..src > elisp
#       (save-excursion
#         body…)
#     < src..
    ..src > elisp
      (save-excursion
        cuerpo…)
    < src..

#     The body of the function is one or more expressions that will be
#     evaluated in sequence by the Lisp interpreter. If there is more than one
#     expression in the body, the value of the last one will be returned as the
#     value of the @c{save-excursion} function. The other expressions in the
#     body are evaluated only for their side effects; and @c{save-excursion}
#     itself is used only for its side effect (which is restoring the positions
#     of point and mark).
    El cuerpo de la función es una o más expresiones que serán evaluadas de
    forma secuencial por el intérprete Lisp. Si hay más de una expresión en
    el cuerpo, el valor de la última será devuelto como el valor de la
    función @c{save-excursion}. Las otras expresiones en el cuerpo solo se
    evaluan por sus efectos secundarios; y @c{save-excursion} en misma solo se
    utiliza por su efecto secundario (que es restaurar las posiciones del
    punto y la marca).

#     In more detail, the template for a @c{save-excursion} expression looks
#     like this:
    La siguiente plantilla explica @c{save-excursion}, con más detalle:

#     ..src > elisp
#       (save-excursion
#         first-expression-in-body
#         second-expression-in-body
#         third-expression-in-body
#          …
#         last-expression-in-body)
#     < src..
    ..src > elisp
      (save-excursion
        primera-expresion-en-el-cuerpo
        segunda-expresion-en-el-cuerpo
        tercera-expresion-en-el-cuerpo
         …
        ultima-expresion-en-el-cuerpo)
    < src..

#     An expression, of course, may be a symbol on its own or a list.
    Una expresión, por supuesto, puede ser un símbolo por sí mismo o una
    lista.

#     In Emacs Lisp code, a @c{save-excursion} expression often occurs within
#     the body of a @c{let} expression. It looks like this:
    En el código Emacs Lisp, una expresión @c{save-excursion} a menudo ocurre
    dentro del cuerpo de una expresión @c{let}. Tiene un aspecto algo asi:

#     ..src > elisp
#       (let varlist
#         (save-excursion
#           body…))
#     < src..
    ..src > elisp
      (let varlist
        (save-excursion
          cuerpo…))
    < src..

# ** Review: How To Write Function Definitions <> Review
** Repaso: Cómo escribir definiciones de funcion <> Repaso

#    In the last few chapters we have introduced a fair number of functions and
#    special forms. Here they are described in brief, along with a few similar
#    functions that have not been mentioned yet.
   En los últimos capítulos se han introducido un buen número de funciones y
   formas especiales. A continuacion se describen brevemente, junto con
   algunas funciones similares que aun no se han mencionado.

#    - @c(eval-last-sexp) ::
   - @c(eval-last-sexp) ::

#      Evaluate the last symbolic expression before the current location of
#      point. The value is printed in the echo area unless the function is
#      invoked with an argument; in that case, the output is printed in the
#      current buffer. This command is normally bound to @k{C-x C-e}.
     Evalúa la última expresión simbólica antes de la posición actual del
     punto. El valor se imprime en el área de eco a menos que la función se
     invoque con un argumento; en este caso, la salida se imprime en el
     búfer actual. Este comando normalmente esta ligado a @k{C-x C-e}.

#    - @c(defun) ::
   - @c(defun) ::

#      Define function. This special form has up to five parts: the name, a
#      template for the arguments that will be passed to the function,
#      documentation, an optional interactive declaration, and the body of the
#      definition.
     Define una función. Esta forma especial consta de hasta cinco partes: el
     nombre, una plantilla para los argumentos que se pasan a la función, la
     documentacion, una declaración interactiva opcional, y el cuerpo de la
     definición.

#      For example, in an early version of Emacs, the function definition was
#      as follows.  (It is slightly more complex now that it seeks the first
#      non-whitespace character rather than the first visible character.)
     Por ejemplo, en las primeras versiones de Emacs, la definición de la
     función @c(back-to-indentation) era la siguiente. (Es ligeramente más
     compleja ahora que busca el primer caracter que no es espacio en lugar
     del primer caracter visible.)

#      ..src > elisp
#        (defun back-to-indentation ()
#          "Move point to first visible character on line."
#          (interactive)
#          (beginning-of-line 1)
#          (skip-chars-forward " \t"))
#      < src..
     ..src > elisp
       (defun back-to-indentation ()
         "Mueve el punto al primer caracter visible de la linea."
         (interactive)
         (beginning-of-line 1)
         (skip-chars-forward " \t"))
     < src..

#    - @c(interactive) ::
   - @c(interactive) ::

#      Declare to the interpreter that the function can be used interactively.
#      This special form may be followed by a string with one or more parts
#      that pass the information to the arguments of the function, in sequence.
#      These parts may also tell the interpreter to prompt for information.
#      Parts of the string are separated by newlines, @'{\n}.
     Anuncia al intérprete que la función se puede usar de forma interactiva.
     Esta forma especial puede ir seguida de una cadena con una o más
     partes que pasan la información a los argumentos de la función, de forma
     secuencial. Estas partes pueden también decir al intérprete que solicite
     información. Las partes de la cadena estan separadas por saltos de
     linea, @'{\n}.

#      Common code characters are:
     Los codigos de caractere comúnes son:

#      - @c(b): The name of an existing buffer.
     - @c(b): El nombre de un búfer existente.

#      - @c(f): The name of an existing file.
     - @c(f): El nombre de un fichero existente

#      - @c(p): The numeric prefix argument.  (Note that this ‘p’ is lower case.)
     - @c(p): El argumento prefijo numérico. (Observa que esta ‘p’ es minúscula.)

#      - @c(r): Point and the mark, as two numeric arguments, smallest first. This
#        is the only code letter that specifies two successive arguments
#        rather than one.
     - @c(r): El punto y la marca, como dos argumentos numéricos, el más pequeño
       primero. Este es el unico codigo de una letra que especifica dos
       argumentos sucesivos en lugar de uno.

#      See Section @l{elisp.html#Interactive Codes<>Code Characters for
#      @'{interactive}} in @e{The GNU Emacs Lisp Reference Manual}, for a
#      complete list of code characters.
     Consulta la Seccion @l{elisp.html#Interactive Codes<>Codigo de caracteres para
     @'{interactive}} en @e(El Manual de Referencia de GNU Emacs Lisp), para
     obtener una lista completa de los codigos de caracteres.

#    - @c(let) ::
   - @c(let) ::

#      Declare that a list of variables is for use within the body of the
#      @c{let} and give them an initial value, either @c{nil} or a specified
#      value; then evaluate the rest of the expressions in the body of the
#      @c{let} and return the value of the last one. Inside the body of the
#      @c{let}, the Lisp interpreter does not see the values of the variables
#      of the same names that are bound outside of the @c{let}.
     Declara una lista de variables para utilizarla dentro del cuerpo de
     @c{let} y darle a cada variable un valor inicial, ya sea @c{nil} o un valor
     específicado; luego evalua el resto de las expresiones en el cuerpo del
     @c{let} y devuelve el valor de la última expresion. Dentro del cuerpo
     del @c{let}, el intérprete Lisp no ve los valores de las variables con el
     mismo nombre declaradas fuera de @c{let}.

#      For example,
     Por ejemplo,

#      ..src > elisp
#        (let ((foo (buffer-name))
#              (bar (buffer-size)))
#          (message "This buffer is %s and has %d characters."
#                   foo bar))
#      < src..
     ..src > elisp
       (let ((foo (buffer-name))
             (bar (buffer-size)))
         (message "Este buffer es %s y tiene %d caracteres."
                  foo bar))
     < src..

#    - @c(save-excursion) ::
   - @c(save-excursion) ::

#      Record the values of point and mark and the current buffer before
#      evaluating the body of this special form. Restore the values of point
#      and mark and buffer afterward.
     Registra los valores de punto, marca y del búfer actual antes de evaluar el
     cuerpo de esta forma especial. Tras evaluar su cuerpo, restaura los valores
     de punto, marca y búfer.

#      For example,
     Por ejemplo,

#      ..src > elisp
#        (message "We are %d characters into this buffer."
#                 (- (point)
#                    (save-excursion
#                      (goto-char (point-min))
#                      (point))))
#      < src..
     ..src > elisp
       (message "Estamos %d caracteres dentro de este buffer."
                (- (point)
                   (save-excursion
                     (goto-char (point-min))
                     (point))))
     < src..


#    - @c(if) ::
   - @c(if) ::

#      Evaluate the first argument to the function; if it is true, evaluate the
#      second argument; else evaluate the third argument, if there is one.
     Evalúa el primer argumento de la función; si es verdadero, evalúa el
     segundo argumento; de otra forma evalúa el tercer argumento, si lo hay.

#      The @c{if} special form is called a @:{conditional}. There are other
#      conditionals in Emacs Lisp, but @c{if} is perhaps the most commonly
#      used.
     La forma especial @c{if} se llamada @:{condicional}. Hay otros
     condicionales en Emacs Lisp, pero @c{if} es quizás el más utilizado.

#      For example,
     Por ejemplo,

#      ..src > elisp
#        (if (= 22 emacs-major-version)
#            (message "This is version 22 Emacs")
#          (message "This is not version 22 Emacs"))
#      < src..
     ..src > elisp
       (if (= 24 emacs-major-version)
           (message "Esta es la version 24 de Emacs")
         (message "Esta no es la version 24 de Emacs"))
     < src..

#    - @c(<), @c(>), @c(<=), @c(>=) ::
   - @c(<), @c(>), @c(<=), @c(>=) ::

#      The @c{<} function tests whether its first argument is smaller than its
#      second argument. A corresponding function, @c{>}, tests whether the
#      first argument is greater than the second. Likewise, @c{<=} tests
#      whether the first argument is less than or equal to the second and
#      @c{>=} tests whether the first argument is greater than or equal to the
#      second. In all cases, both arguments must be numbers or markers
#      (markers indicate positions in buffers).
     La función @c{<} prueba si su primer argumento es menor que el segundo.
     @c{>}, prueba si el primer argumento es mayor que el segundo. Del mismo
     modo, @c{<=} prueba si el primer argumento es menor o igual al segundo y
     @c{>=} si el primer argumento es mayor o igual al segundo. En todos los
     casos, ambos argumentos deben ser números o marcadores (los marcadores
     indican posiciones en búfers).

#    - @c(=) ::
   - @c(=) ::

#      The @c{=} function tests whether two arguments, both numbers or markers,
#      are equal.
     La función @c{=} prueba si dos argumentos, ambos números o marcadores,
     son iguales.

#    - @c(equal), @c(eq) ::
   - @c(equal), @c(eq) ::

#      Test whether two objects are the same.  @c{equal} uses one meaning of
#      the word ‘same’ and @c{eq} uses another: @c{equal} returns true if the
#      two objects have a similar structure and contents, such as two copies of
#      the same book. On the other hand, @c{eq}, returns true if both
#      arguments are actually the same object.
     Prueban si dos objetos son el mismo. @c{equal} utiliza un signicado de la
     palabra ‘mismo’ y @c{eq} utiliza otro: @c{equal} devuelve verdadero si
     los dos objetos tienen una estructura y contenidos similares, por
     ejemplo, dos copias del mismo libro. Por otro lado, @c{eq}, devuelve
     verdadero si ambos argumentos son realmente el mismo objeto.

#    - @c(string<), @c(string-lessp), @c(string=), @c(string-equal) ::
   - @c(string<), @c(string-lessp), @c(string=), @c(string-equal) ::

#      The @c{string-lessp} function tests whether its first argument is
#      smaller than the second argument. A shorter, alternative name for the
#      same function (a @c{defalias}) is @c{string<}.
     La función @c{string-lessp} prueba si su primer argumento es menor que el
     segundo. Un nombre alternativo mas corto para la misma función (un
     @c{defalias}) es @c{string<}.

#      The arguments to @c{string-lessp} must be strings or symbols; the
#      ordering is lexicographic, so case is significant. The print names of
#      symbols are used instead of the symbols themselves.
     Los argumentos para @c{string-lessp} deben ser cadenas o símbolos; la
     ordenación es lexicográfica, por lo que mayusculas o minusculas son
     significativas. Los nombres impresos de símbolos se utilizan en lugar de
     los símbolos mismos.

#      An empty string, @'c{""}, a string with no characters in it, is smaller
#      than any string of characters.
     Una cadena vacía, @'c{""}, una cadena sin caracteres, es más pequeña que
     cualquier cadena de caracteres.

#      @c{string-equal} provides the corresponding test for equality. Its
#      shorter, alternative name is @c{string=}. There are no string test
#      functions that correspond to @c{>}, @c{>=}, or @c{<=}.
     @c{string-equal} proporciona la prueba correpondiente para la igualdad.
     Su nombre alternativo es @c{string=}. No hay funciones de prueba
     de cadenas que correspondan a @c{>}, @c{>=} o @c{<=}.

#    - @c(message) ::
   - @c(message) ::

#      Print a message in the echo area. The first argument is a string that
#      can contain @'c{%s}, @'c{%d}, or @'c{%c} to print the value of arguments
#      that follow the string. The argument used by @'c{%s} must be a string or
#      a symbol; the argument used by @'c{%d} must be a number. The argument
#      used by @'c{%c} must be an @A{ASCII} code number; it will be printed as
#      the character with that @A{ASCII} code.  (Various other %-sequences
#      have not been mentioned.)
     Imprime un mensaje en el área de eco. El primer argumento es una cadena
     que puede contener, @'c{%s}, @'c{%d}, o @'c{%c} para imprimir el valor de
     los argumentos que siguen a la cadena. El argumento utilizado por
     @'c{%s} debe ser una cadena o un simbolo, el argumeto utilizado por
     @'c{%d} debe ser un número. El argumento usado por @'c{%c} debe ser un
     codigo númerico @A{ASCII}; se imprimira como el caracter con ese código
     @A{ASCII}. (No se han mencionado otras secuencias @"(porcentuales) @c(%-)).

#    - @c(setq), @c(set) ::
   - @c(setq), @c(set) ::

#      The @c{setq} function sets the value of its first argument to the value
#      of the second argument. The first argument is automatically quoted by
#      @c{setq}. It does the same for succeeding pairs of arguments. Another
#      function, @c{set}, takes only two arguments and evaluates both of them
#      before setting the value returned by its first argument to the value
#      returned by its second argument.
     La función @c{setq} asigna al valor de su primer argumento el valor del
     segundo argumento. El primer argumento se cita automáticamente por
     @c{setq}. Hace lo mismo para los pares sucesisvos de argumentos. La
     función, @c{set}, toma solo dos argumentos y evalúa ambos antes de
     asignar el valor devuelto por su primer argumento al valor devuelto por
     el segundo argumento.

#    - @c(buffer-name) ::
   - @c(buffer-name) ::

#      Without an argument, return the name of the buffer, as a string.
     Sin un argumento, devuelve el nombre del búfer, como una cadena.

#    - @c(buffer-file-name) ::
   - @c(buffer-file-name) ::

#      Without an argument, return the name of the file the buffer is visiting.
     Sin un argumento, devuelve el nombre del fichero del búfer que se esta
     visitando.

#    - @c(current-buffer) ::
   - @c(current-buffer) ::

#      Return the buffer in which Emacs is active; it may not be the buffer
#      that is visible on the screen.
     Devuelve el búfer en el que Emacs se encuentra activo; Puede que no sea
     el búfer que es visible en la pantalla.

#    - @c(other-buffer) ::
   - @c(other-buffer) ::

#      Return the most recently selected buffer (other than the buffer passed
#      to @c{other-buffer} as an argument and other than the current buffer).
     Devuelve el ultimo búfer seleccionado mas recientemente (distinto del
     buffer pasado a @c{other-buffer} como un argumento y distinto del búfer
     actual).

#    - @c(switch-to-buffer) ::
   - @c(switch-to-buffer) ::

#      Select a buffer for Emacs to be active in and display it in the current
#      window so users can look at it. Usually bound to @k{C-x b}.
     Selecciona un búfer de Emacs para activarlo y mostralo en la ventana
     actual para que los usuarios puedan verlo. Normalmente ligado a @k{C-x b}.

#    - @c(set-buffer) ::
   - @c(set-buffer) ::

#      Switch Emacs's attention to a buffer on which programs will run. Don't
#      alter what the window is showing.
     Cambiar la atención de Emacs a un búfer en el que se ejecutaran
     los programas. No altera lo que muestra la ventana.

#    - @c(buffer-size) ::
   - @c(buffer-size) ::

#      Return the number of characters in the current buffer.
     Devuelve el número de caracteres en el búfer actual.

#    - @c(point) ::
   - @c(point) ::

#      Return the value of the current position of the cursor, as an integer
#      counting the number of characters from the beginning of the buffer.
     Devuelve el valor de la posicion actual del cursor, como un entero
     contando el número de caracteres desde el inicio del búfer.

#    - @c(point-min) ::
   - @c(point-min) ::

#      Return the minimum permissible value of point in the current buffer.
#      This is 1, unless narrowing is in effect.
     Devuelve el valor mínimo admisible del punto en el búfer actual. Esto
     es 1, a menos que narrowing esté activo

#    - @c(point-max) ::
   - @c(point-max) ::

#      Return the value of the maximum permissible value of point in the
#      current buffer. This is the end of the buffer, unless narrowing is in
#      effect.
     Devuelve el valor máximo admisible del punto en el búfer actual.
     Este es el fin del búfer, a menos que narrowing este activo.

# ** Exercises
** Ejercicios

#    - Write a non-interactive function that doubles the value of its argument,
#      a number. Make that function interactive.
   - Escribe una función no interactiva que duplique el valor de su
     argumento, un número. Luego haz la función interactiva.

#    - Write a function that tests whether the current value of @c{fill-column}
#      is greater than the argument passed to the function, and if so, prints
#      an appropriate message.
   - Escribe una función que compruebe si el valor actual de @c{fill-column}
     es mayor que el argumento pasado a la función, y si es así, imprime un
     mensaje apropiado.

# * A Few Buffer––Related Functions
* Algunas funciones relacionadas al búfer

#   In this chapter we study in detail several of the functions used in GNU
#   Emacs. This is called a “walk-through”. These functions are used as
#   examples of Lisp code, but are not imaginary examples; with the exception
#   of the first, simplified function definition, these functions show the
#   actual code used in GNU Emacs. You can learn a great deal from these
#   definitions. The functions described here are all related to buffers.
#   Later, we will study other functions.
  En este capítulo estudiamos en detalle varias de las funciones usadas en GNU
  Emacs. Esto se denomina “walk-through” @%i(recorrido) (visita o demostracion
  de un area o tarea). Estas funciones se utilizan como ejemplos de código Lisp,
  pero no son ejemplos imaginarios; con excepción del primero, con la definición
  de función simplificada, estas funciones muestran el código real usado en GNU
  Emacs. Se puede aprender mucho de estas definiciones. Las funciones aquí
  descritas están relacionadas a los búfers. Mas tarde, estudiaremos otras
  funciones.

# ** Finding More Information
** Buscar Más Información

#    In this walk-through, I will describe each new function as we come to it,
#    sometimes in detail and sometimes briefly. If you are interested, you can
#    get the full documentation of any Emacs Lisp function at any time by
#    typing @k{C-h f} and then the name of the function (and then @k{RET}).
#    Similarly, you can get the full documentation for a variable by typing
#    @k{C-h v} and then the name of the variable (and then @k{RET}).
   En este @"(recorrido), describire cada nueva función a medida que lleguemos a
   ella, a veces en detalle y a veces brevemente. Si estás interesado, puedes
   obtener la documentación completa de cualquier función de Emacs Lisp en
   cualquier momento presionando @k{C-h f} y luego ingresando el nombre de la función
   (y luego @k{RET}). Del mismo modo, se puede obtener la documentación completa
   de una variable con @k{C-h v}, luego el nombre de la variable (y despues
   @k{RET}).

#    Also, @c{describe-function} will tell you the location of the function
#    definition.
   Ademas, @c{describe-function} te dira la ubicacion de la definición de la
   función.

#    Put point into the name of the file that contains the function and press
#    the @k{RET} key. In this case, @k{RET} means @c{push-button} rather than
#    ‘return’ or ‘enter’. Emacs will take you directly to the function
#    definition.
   Coloca el punto sobre el nombre del fichero que contiene la función y
   presiona la tecla @k{RET}. En este caso, @k{RET} significa @c{push-button}
   en lugar de ‘return’ o ‘enter’. Emacs te llevara directamente a la
   definición de la función.

#    More generally, if you want to see a function in its original source file,
#    you can use the @c{find-tag} function to jump to it.  @c{find-tag} works
#    with a wide variety of languages, not just Lisp, and C, and it works with
#    non-programming text as well. For example, @c{find-tag} will jump to the
#    various nodes in the Texinfo source file of this document. The
#    @c{find-tag} function depends on ‘tags tables’ that record the locations
#    of the functions, variables, and other items to which @c{find-tag} jumps.
   De manera más general, si quieres ver una función en su fichero fuente
   original, puedes utilizar la función @c{find-tag} para saltar a la misma.
   @c{find-tag} trabaja con una amplia variedad de lenguajes, no solo Lisp, y C,
   y tambien funciona con texto en general. Por ejemplo, @c{find-tag} saltará a
   los distintos nodos del codigo fuente de este documento. La función
   @c{find-tag} depende de ‘tablas de etiquetas’ que registran las ubicaciones
   de las funciones, variables, y otros elementos a los que @c{find-tag} salta.

#    To use the @c{find-tag} command, type @k{M-.}  (i.e., press the period key
#    while holding down the @k{META} key, or else type the @k{ESC} key and then
#    type the period key), and then, at the prompt, type in the name of the
#    function whose source code you want to see, such as @c{mark-whole-buffer},
#    and then type @k{RET}. Emacs will switch buffers and display the source
#    code for the function on your screen. To switch back to your current
#    buffer, type @k{C-x b @k{RET}}.  (On some keyboards, the @k{META} key is
#    labeled @k{ALT}.)
   Para usar el comando @c{find-tag}, presiona @k{M-.} (es decir, presiona la
   tecla punto mientras presionas la tecla @k(META), o presiona @k{ESC} y
   luego la tecla punto), a continuacion, en el prompt, escribe el nombre de
   la función para ver su código fuente, por ejemplo @c{mark-whole-buffer}, y
   luego pulsa @k{RET}. Emacs cambiará de búfer y mostrará el código fuente
   de la función en la pantalla. Para regresar a tu búfer actual, presiona
   @k{C-x b RET}. (En algunos teclados, la tecla @k{META} se etiqueta como
   @k{ALT}.)

#    Depending on how the initial default values of your copy of Emacs are
#    set, you may also need to specify the location of your ‘tags table’,
#    which is a file called @f{TAGS}. For example, if you are interested in
#    Emacs sources, the tags table you will most likely want, if it has
#    already been created for you, will be in a subdirectory of the
#    @f{/usr/local/share/emacs/} directory; thus you would use the @c{M-x
#    visit-tags-table} command and specify a pathname such as
#    @f{/usr/local/share/emacs/22.1.1/lisp/TAGS}. If the tags table has not
#    already been created, you will have to create it yourself. It will be
#    in a file such as @f{/usr/local/src/emacs/src/TAGS}.
   Dependiendo de la configuracion de los valores iniciales predeterminados de
   tu copia de Emacs, puede ser necesario especificar la posición de tu ‘tabla
   de etiquetas’, que es un fichero llamado @f{TAGS}. Por ejemplo, si estás
   interesado en el codigo fuente de Emacs, lo mas probable es que la tabla de
   etiquetas que deseas, si ya ha sido creada, este en un subdirectorio del
   directorio @f{/usr/local/share/emacs}; de este modo se usaría el comando
   @c{M-x visit-tags-table} y se especificaria una ruta como
   @f{/usr/local/share/emacs/24.1.1/lisp/TAGS}. Si la tabla de etiquetas no ha
   sido creada, tendrás que crearla por tí mismo. Estara en un fichero como
   @f{/usr/local/src/emacs/src/TAGS}.

#    To create a @f{TAGS} file in a specific directory, switch to that
#    directory in Emacs using @k{M-x cd} command, or list the directory with
#    @k{C-x d} @%c(dired). Then run the @c(compile) command, with @c{etags *.el}
#    as the command to execute:
   Para crear un fichero @f{TAGS} en un directorio específico, cambia a ese
   directorio en Emacs utilizando el comando @k{M-x cd}, o lista el directorio
   con @k{C-x d} @%c(dired). A continuacion ejecuta el comando @c(compile), con
   @c{etags *.el} asi:

#    ..example >
#      M-x compile RET etags *.el RET
#    < example..
   ..example >
     M-x compile RET etags *.el RET
   < example..

#    For more information, see Section @l{#Create Your Own @f{TAGS} File}.
   Para más información, consulta la Seccion @l{#Crea tu propio fichero @f{TAGS}}.

#    After you become more familiar with Emacs Lisp, you will find that you
#    will frequently use @c{find-tag} to navigate your way around source code;
#    and you will create your own @f{TAGS} tables.
   Después de que te familiarices con Emacs Lisp, encontrarás que utilizas con
   frecuencia @c{find-tag} como metodo para navegar por el código fuente; y
   crearás tus propias tablas @f{TAGS}.

#    Incidentally, the files that contain Lisp code are conventionally called
#    @:{libraries}. The metaphor is derived from that of a specialized
#    library, such as a law library or an engineering library, rather than a
#    general library. Each library, or file, contains functions that relate to
#    a particular topic or activity, such as @f{abbrev.el} for handling
#    abbreviations and other typing shortcuts, and @f{help.el} for on-line
#    help.  (Sometimes several libraries provide code for a single activity, as
#    the various @f{rmail…} files provide code for reading electronic mail.)
#    In @e{The GNU Emacs Manual}, you will see sentences such as “The @k{C-h p}
#    command lets you search the standard Emacs Lisp libraries by topic
#    keywords.”
   Por cierto, los ficheros que contienen código Lisp se denominan
   convencionalmente @:{librerías}. La metáfora se deriva que una librería
   especializada, como una librería de leyes o una librería de
   ingeniería, en lugar de una librería general. Cada librería, o fichero,
   contiene funciones que se relacionan con un tema o actividad particular,
   por ejemplo @f{abbrev.el} para manejar abreviaturas y atajos, y
   @f{help.el} para la ayuda en linea. (Algunas veces varias librerías
   proporcionan código para una sola actividad, como los distintos ficheros
   @f{rmail…}  que proporcionan codigo para leer correo electrónico.) En @e{El
   Manual de GNU Emacs}, verás frases como “El comando @k{C-h p} te
   permite buscar las librerias estándar de Emacs Lisp por palabras clave
   del tema.”

# ** A Simplified @c{beginning-of-buffer} Definition
** Una definición simplificada de @c{beginning-of-buffer}

#    The @c{beginning-of-buffer} command is a good function to start with since
#    you are likely to be familiar with it and it is easy to understand. Used
#    as an interactive command, @c{beginning-of-buffer} moves the cursor to the
#    beginning of the buffer, leaving the mark at the previous position. It is
#    generally bound to @k{M-<}.
   El comando @c{beginning-of-buffer} es una buena función para empezar, ya
   que es probable que estes familiarizado con ella y es fácil de
   entender. Utilizado como un comando interactivo, @c{beginning-of-buffer} mueve
   el cursor al inicio del búfer, dejando la marca en la posición
   anterior. Esta generalmente ligado a @k{M-<}.

#    In this section, we will discuss a shortened version of the function that
#    shows how it is most frequently used. This shortened function works as
#    written, but it does not contain the code for a complex option. In
#    another section, we will describe the entire function.  (See Section
#    @l{#Complete Definition of @c{beginning-of-buffer}}.)
   En esta sección, discutiremos una versión reducida de la función que
   muestra como se utiliza con mayor frecuencia. Esta función reducida
   funciona como esta escrita, pero no contiene código para una opcion
   compleja. En otra sección, describiremos la función completa. (Consulta la Seccion
   @l(#Definición completa de @c{beginning-of-buffer}).

#    Before looking at the code, let's consider what the function definition
#    has to contain: it must include an expression that makes the function
#    interactive so it can be called by typing @k{M-x beginning-of-buffer} or
#    by typing a keychord such as @k{M-<}; it must include code to leave a mark
#    at the original position in the buffer; and it must include code to move
#    the cursor to the beginning of the buffer.
   Antes de mirar el código, consideremos lo que debe contener la definición de
   función: debe incluir una expresión que haga que la función sea interactiva
   para que puede llamarse tecleando @k{M-x beginning-of-buffer} o pulsando algun
   atajo como @k{M-<}; debe incluir código para dejar una marca en la posición
   original del búfer; y debe incluir código para mover el cursor al inicio del
   búfer.

#    Here is the complete text of the shortened version of the function:
   Aquí está el texto completo la versión reducida de la función:

#    ..src > elisp
#      (defun simplified-beginning-of-buffer ()
#        "Move point to the beginning of the buffer;
#      leave mark at previous position."
#        (interactive)
#        (push-mark)
#        (goto-char (point-min)))
#    < src..
   ..src > elisp
     (defun beginning-of-buffer-simplificado ()
       "Mueve el punto al inicio del buffer;
     deja la marca en la posicion anterior."
       (interactive)
       (push-mark)
       (goto-char (point-min)))
   < src..

#    Like all function definitions, this definition has five parts following
#    the special form @c{defun}:
   Como todas las definiciones de función, esta definición tiene
   cinco partes que siguen la forma especial @c{defun}:

#    1. The name: in this example, @c{simplified-beginning-of-buffer}.
   1. El nombre: en este ejemplo, @c{beginning-of-buffer-simplificado}.

#    2. A list of the arguments: in this example, an empty list, @c{()},
   2. Una lista de argumentos: en este ejemplo, una lista vacía, @c{()},

#    3. The documentation string.
   3. La cadena de documentación.

#    4. The interactive expression.
   4. La expresión interactiva.

#    5. The body.
   5. El cuerpo.


#    In this function definition, the argument list is empty; this means that
#    this function does not require any arguments.  (When we look at the
#    definition for the complete function, we will see that it may be passed an
#    optional argument.)
   En esta definición de función, la lista de argumentos está vacía; esto
   significa que esta función no requiere ningun argumento. (Cuando
   veamos la definición de la función completa, veremos que se puede
   pasar un argumento opcional.)

#    The interactive expression tells Emacs that the function is intended to be
#    used interactively. In this example, @c{interactive} does not have an
#    argument because @c{simplified-beginning-of-buffer} does not require one.
   La expresión interactiva le indica a Emacs que se pretende utilizar la
   función de forma interactiva. En este ejemplo, @c{interactive} no tiene un
   argumento porque @c{beginning-of-buffer-simplificado} no lo requiere.

#    The body of the function consists of the two lines:
   El cuerpo de la función esta formado por dos líneas:

#    ..src > elisp
#      (push-mark)
#      (goto-char (point-min))
#    < src..
   ..src > elisp
     (push-mark)
     (goto-char (point-min))
   < src..

#    The first of these lines is the expression, @c{(push-mark)}. When this
#    expression is evaluated by the Lisp interpreter, it sets a mark at the
#    current position of the cursor, wherever that may be. The position of
#    this mark is saved in the mark ring.
   La primera de estas líneas es la expresión, @c{(push-mark)}. Cuando el
   interprete Lisp evalua esta expresión, pone una marca en la posición actual
   del cursor, donde sea que este. La posición de esta marca se guarda en el
   anillo de marcas.

#    The next line is @c{(goto-char (point-min))}. This expression jumps the
#    cursor to the minimum point in the buffer, that is, to the beginning of
#    the buffer (or to the beginning of the accessible portion of the buffer if
#    it is narrowed. See Section @l{#Narrowing and Widening}.)
   La siguiente línea es @c{(goto-char (point-min))}. Esta expresión hace
   saltar el cursor hasta el punto mínimo en el búfer, es decir, al inicio
   del búfer (o al inicio de la porción accesible del búfer si narrowed
   esta activo. Consulta la Seccion @l{#Reducir y Extender}.)

#    The @c{push-mark} command sets a mark at the place where the cursor was
#    located before it was moved to the beginning of the buffer by the
#    @c{(goto-char (point-min))} expression. Consequently, you can, if you
#    wish, go back to where you were originally by typing @k{C-x C-x}.
   El comando @c{push-mark} establece una marca en el sitio donde se encontraba
   el cursor antes de que la expresión @c{(goto-char (point-min))} lo
   moviera al principio del bufer. En consecuencia, puedes, si quieres, volver a
   donde estabas originalmente presionando @k{C-x C-x}.

#    That is all there is to the function definition!
   ¡Esto es todo lo que hay en la definición de función!

#    When you are reading code such as this and come upon an unfamiliar
#    function, such as @c{goto-char}, you can find out what it does by using
#    the @c{describe-function} command. To use this command, type @k{C-h f}
#    and then type in the name of the function and press @k{RET}. The
#    @c{describe-function} command will print the function's documentation
#    string in a @f{*Help*} window. For example, the documentation for
#    @c{goto-char} is:
   Cuando leas código como este y te encuentres con una función desconocida,
   como @c{goto-char}, puedes averiguar que es lo que hace mediante el
   comando @c{describe-function}. Para usar este comando, presiona @k{C-h f},
   luego escribe el nombre de la función y presiona @k{RET}. El comando
   @c{describe-function} imprimirá la cadena de documentacion de la función
   en una ventana @f{*Help*}. Por ejemplo, la documentación de @c{goto-char}
   es:

#    ..example >
#      Set point to POSITION, a number or marker.
#      Beginning of buffer is position (point-min), end is (point-max).
#    < example..
   ..example >
     Establece el punto a POSICION, un numero o marcador.
     El inicio del buffer es la posicion (point-min), el final es (point-max).
   < example..

#    The function's one argument is the desired position.
   El argumento de la función es la posición deseada.

#    (The prompt for @c{describe-function} will offer you the symbol under or
#    preceding the cursor, so you can save typing by positioning the cursor
#    right over or after the function and then typing @k{C-h f @k{RET}}.)
   (En el caso de @c{describe-function} el prompt te facilita el símbolo
   adelante o debaje del cursor, lo que te puede evitar escribir el nombre de
   la funcion al colocar el cursor encima o después de la función y luego
   presionar @k{C-h f RET}.)

#    The @c{end-of-buffer} function definition is written in the same way as
#    the @c{beginning-of-buffer} definition except that the body of the
#    function contains the expression @c{(goto-char (point-max))} in place of
#    @c{(goto-char (point-min))}.
   La definición de la función @c{end-of-buffer} se escribe de la misma forma
   que la definición @c{beginnig-of-buffer} excepto que el cuerpo de la
   función contiene la expresión @c{(goto-char (point-max))} en lugar de
   @c{(goto-char (point-min))}

# ** The Definition of @c{mark-whole-buffer}
** La definición de @c{mark-whole-buffer}

#    The @c{mark-whole-buffer} function is no harder to understand than the
#    @c{simplified-beginning-of-buffer} function. In this case, however, we
#    will look at the complete function, not a shortened version.
   La función @c{mark-whole-buffer} no es mas difícil de entender que la
   función @c{beginning-of-buffer-simplificado}. En este caso, sin embargo,
   veremos la función completa, no una versión reducida.

#    The @c{mark-whole-buffer} function is not as commonly used as the
#    @c{beginning-of-buffer} function, but is useful nonetheless: it marks a
#    whole buffer as a region by putting point at the beginning and a mark at
#    the end of the buffer. It is generally bound to @k{C-x h}.
   La función @c{mark-whole-buffer} no se utiliza con tanta frecuencia como la
   función @c{beginning-of-buffer}, pero no es menos útil: marca un búfer
   completo como una región colocando el punto al inicio y una marca al final
   del búfer. Generalmente se enlaza a @k{C-x h}.

#    In GNU Emacs 22, the code for the complete function looks like this:
   En GNU Emacs 22, el código de la función completa se ve asi:

#    ..src > elisp
#      (defun mark-whole-buffer ()
#        "Put point at beginning and mark at end of buffer.
#      You probably should not use this function in Lisp programs;
#      it is usually a mistake for a Lisp function to use any subroutine
#      that uses or sets the mark."
#        (interactive)
#        (push-mark (point))
#        (push-mark (point-max) nil t)
#        (goto-char (point-min)))
#    < src..
   ..src > elisp
     (defun mark-whole-buffer ()
       "Coloca el punto al inicio y la marca el final del buffer.
     Probablemente no deberias utilizar esta funcion en programas Lisp;
     Por lo general es un error que una funcion Lisp utilice cualquier subrutina
     que utilice o establesca la marca."
       (interactive)
       (push-mark (point))
       (push-mark (point-max) nil t)
       (goto-char (point-min)))
   < src..

#    Like all other functions, the @c{mark-whole-buffer} function fits into the
#    template for a function definition. The template looks like this:
   Al igual que todas las demas funciones, la función @c{mark-whole-buffer}
   encaja dentro de la plantilla de una definición de funcion. La
   plantilla luce asi:

#    ..src > elisp
#      (defun name-of-function (argument-list)
#        "documentation…"
#        (interactive-expression…)
#        body…)
#    < src..
   ..src > elisp
     (defun nombre-de-funcion (lista-de-argumentos)
       "documentacion…"
       (expresion-interactiva…)
       cuerpo…)
   < src..

#    Here is how the function works: the name of the function is
#    @c{mark-whole-buffer}; it is followed by an empty argument list, @'c{()},
#    which means that the function does not require arguments. The
#    documentation comes next.
   Asi es cómo funciona la función: el nombre de la función es
   @c{mark-whole-buffer}; le sigue una lista de argumentos vacía, @'c{()}, lo que
   significa que la función no requiere argumentos. La documentación viene despues.

#    The next line is an @c{(interactive)} expression that tells Emacs that the
#    function will be used interactively. These details are similar to the
#    @c{simplified-beginning-of-buffer} function described in the previous
#    section.
   La siguiente línea es una expresión @c{(interactive)} que indica a Emacs
   que la función se utilizara de forma interactiva. Estos detalles son
   similares a la función @c{beginning-of-buffer-simplificado} descrita en la
   sección anterior

# *** Body of @c{mark-whole-buffer}
*** Cuerpo de @c{mark-whole-buffer}

#     The body of the @c{mark-whole-buffer} function consists of three lines of
#     code:
    El cuerpo de la función @c{mark-whole-buffer} consiste en tres líneas de
    código:

#     ..src > elisp
#       (push-mark (point))
#       (push-mark (point-max) nil t)
#       (goto-char (point-min))
#     < src..
    ..src > elisp
      (push-mark (point))
      (push-mark (point-max) nil t)
      (goto-char (point-min))
    < src..

#     The first of these lines is the expression, @c{(push-mark (point))}.
    La primera de estas líneas es la expresión, @c{(push-mark (point))}.

#     This line does exactly the same job as the first line of the body of the
#     @c{simplified-beginning-of-buffer} function, which is written
#     @c{(push-mark)}. In both cases, the Lisp interpreter sets a mark at the
#     current position of the cursor.
    Esta línea hace exactamente el mismo trabajo que la primera línea del
    cuerpo de la función @c{beginning-of-buffer-simplificado}, en la que solo
    se escribe @c[(push-mark)]. En ambos casos, el intérprete Lisp coloca una
    marca en la posición actual del cursor.

#     I don't know why the expression in @c{mark-whole-buffer} is written
#     @c{(push-mark (point))} and the expression in @c{beginning-of-buffer} is
#     written @c{(push-mark)}. Perhaps whoever wrote the code did not know
#     that the arguments for @c{push-mark} are optional and that if
#     @c{push-mark} is not passed an argument, the function automatically sets
#     mark at the location of point by default. Or perhaps the expression was
#     written so as to parallel the structure of the next line. In any case,
#     the line causes Emacs to determine the position of point and set a mark
#     there.
    No sé por qué en la expresión @c{mark-whole-buffer} se escribe @c{(push-mark
    (point))} y en la expresión @c{beginning-of-buffer} se escribe
    @c{(push-mark)}. Quizás quien escribió el código no conocia que los
    argumentos de @c{push-mark} son opcionales y que si no se pasa un argumento
    a @c{push-mark}, la función establece automáticamente la marca en la
    posicion del punto por defecto. O quizás la expresión fué escrita de manera
    que fuera paralela a la estructura de la siguiente línea. En cualquier caso,
    la línea hace que Emacs determine la posición del punto y coloque una
    marca allí.

#     In earlier versions of GNU Emacs, the next line of @c{mark-whole-buffer}
#     was @c{(push-mark (point-max))}. This expression sets a mark at the
#     point in the buffer that has the highest number. This will be the end of
#     the buffer (or, if the buffer is narrowed, the end of the accessible
#     portion of the buffer. See Section @l{#Narrowing and Widening}, for more
#     about narrowing.)  After this mark has been set, the previous mark, the
#     one set at point, is no longer set, but Emacs remembers its position,
#     just as all other recent marks are always remembered. This means that
#     you can, if you wish, go back to that position by typing @k{C-u
#     C-@k{SPC}} twice.
    En versiones anteriores de GNU Emacs, la siguiente línea de
    @c{mark-whole-buffer} era @c{(push-mark (point-max))}. Esta expresión
    establece una marca en el punto del búfer que tiene el número más alto. Este
    será el final del búfer (o, si el búfer tiene activo narrowing, el final de
    la porción accesible del búfer. Consulta la Seccion @l{#Reducir y Extender}, para
    más informacion sobre norrowing). Después de colocar esta marca, la marca
    anterior, la establecida en el punto, ya no esta establecida, pero Emacs
    recuerda su posición, al igual que todas las otras marcas recientes. Esto
    significa que, si lo deseas, puedes volver a esta posición presionando @k{C-u
    C-SPC} dos veces.

#     In GNU Emacs 22, the @c{(point-max)} is slightly more complicated. The
#     line reads
    En GNU Emacs 22, @c{(point-max)} es ligeramente más complicado. La
    línea es

#     ..src > elisp
#       (push-mark (point-max) nil t)
#     < src..
    ..src > elisp
      (push-mark (point-max) nil t)
    < src..

#     The expression works nearly the same as before. It sets a mark at the
#     highest numbered place in the buffer that it can. However, in this
#     version, @c{push-mark} has two additional arguments. The second argument
#     to @c{push-mark} is @c{nil}. This tells the function it @e{should}
#     display a message that says ‘Mark set’ when it pushes the mark. The
#     third argument is @c{t}. This tells @c{push-mark} to activate the mark
#     when Transient Mark mode is turned on. Transient Mark mode highlights
#     the currently active region. It is often turned off.
    La expresión funciona casi igual que antes. Establece una marca en la
    posicion con el numero mas alto posible en el búfer. Sin embargo, en
    esta versión, @c{push-mark} tiene dos argumentos adicionales. El segundo
    argumento de @c{push-mark} es @c{nil}. Esto le indica a la función que debe
    @e{mostrar} un mensaje que diga ‘Mark set’ cuando se coloca la marca. El
    tercer argumento es @c{t}. Esto le indica a @c{push-mark} que active la
    marca cuando el modo Transient Mark está activo. El modo Transient Mark
    resalta la región activa. Con frecuencia esta desactivado.

#     Finally, the last line of the function is @c{(goto-char (point-min)))}.
#     This is written exactly the same way as it is written in
#     @c{beginning-of-buffer}. The expression moves the cursor to the minimum
#     point in the buffer, that is, to the beginning of the buffer (or to the
#     beginning of the accessible portion of the buffer). As a result of this,
#     point is placed at the beginning of the buffer and mark is set at the end
#     of the buffer. The whole buffer is, therefore, the region.
    Finalmente, la última línea de la función es @c{(goto-char (point-min)))}.
    Se escribe exactamente de la misma forma como se escribio
    @c{beginning-of-buffer}. La expresión mueve el cursor al punto mínimo en el
    búfer, es decir, al inicio del búferr (o al inicio de la porción accesible
    del búfer). Como resultado de esto, el punto se coloca al inicio del búfer y la
    marca se encuentra al final del búfer. Por tanto, la región es todo el búfer.

# ** The Definition of @c{append-to-buffer}
** La definición de @c{append-to-buffer}

#    The @c{append-to-buffer} command is more complex than the
#    @c{mark-whole-buffer} command. What it does is copy the region (that is,
#    the part of the buffer between point and mark) from the current buffer to
#    a specified buffer.
   El comando @c{append-to-buffer} es más complejo que el comando
   @c{mark-whole-buffer}. Lo que hace es copiar la región (es decir, la parte
   del búfer entre el punto y la marca) del buffer actual a un búfer
   específico.

#    The @c{append-to-buffer} command uses the @c{insert-buffer-substring}
#    function to copy the region.  @c{insert-buffer-substring} is described by
#    its name: it takes a string of characters from part of a buffer, a
#    “substring”, and inserts them into another buffer.
   El comando @c{append-to-buffer} utiliza la función @c{insert-buffer-substring}
   para copiar la región. @c{insert-buffer-substring} se describe por su nombre:
   toma una cadena de caracteres de una parte de un búfer, una “subcadena”, y la
   inserta en otro búfer.

#    Most of @c{append-to-buffer} is concerned with setting up the conditions
#    for @c{insert-buffer-substring} to work: the code must specify both the
#    buffer to which the text will go, the window it comes from and goes to,
#    and the region that will be copied.
   La mayor parte de @c{append-to-buffer} tiene que ver con establecer las
   condiciones para que @c{insert-buffer-substring} funcione: el código debe
   especificar tanto el búfer al que ira el texto, la ventana de la que viene y
   a la que va, como la región que será copiada.

#    Here is the complete text of the function:
   Aquí está el texto completo de la función:

#    ..src > elisp
   ..src > elisp
#      (defun append-to-buffer (buffer start end)
#        "Append to specified buffer the text of the region.
#      It is inserted into that buffer before its point.
     (defun append-to-buffer (buffer start end)
       "Añade al buffer especificado el texto de la region.
     Este se inserta en ese buffer antes de su punto.

#      When calling from a program, give three arguments:
#      BUFFER (or buffer name), START and END.
#      START and END specify the portion of the current buffer to be copied."
     Cuando se llama desde un programa, se pasan tres argumentes:
     BUFFER (o nombre del buffer), START y END.
     START y END especifican la porcion del buffer actual a copiar."
#        (interactive
#         (list (read-buffer "Append to buffer: " (other-buffer
#                                                  (current-buffer) t))
#               (region-beginning) (region-end)))
       (interactive
        (list (read-buffer "Agregar al buffer: " (other-buffer
                                                 (current-buffer) t))
              (region-beginning) (region-end)))
#        (let ((oldbuf (current-buffer)))
#          (save-excursion
#            (let* ((append-to (get-buffer-create buffer))
#                   (windows (get-buffer-window-list append-to t t))
#                   point)
#              (set-buffer append-to)
#              (setq point (point))
#              (barf-if-buffer-read-only)
#              (insert-buffer-substring oldbuf start end)
#              (dolist (window windows)
#                (when (= (window-point window) point)
#                  (set-window-point window (point))))))))
       (let ((oldbuf (current-buffer)))
         (save-excursion
           (let* ((append-to (get-buffer-create buffer))
                  (windows (get-buffer-window-list append-to t t))
                  point)
             (set-buffer append-to)
             (setq point (point))
             (barf-if-buffer-read-only)
             (insert-buffer-substring oldbuf start end)
             (dolist (window windows)
               (when (= (window-point window) point)
                 (set-window-point window (point))))))))
#    < src..
   < src..

#    The function can be understood by looking at it as a series of filled-in
#    templates.
   Se puede entender la función si se mira como una serie de plantillas
   llenas.

#    The outermost template is for the function definition. In this function,
#    it looks like this (with several slots filled in):
   La plantilla exterior es para la definición de función. Esta función, se
   ve asi (con varios espacios ocupados):

#    ..src > elisp
#      (defun append-to-buffer (buffer start end)
#        "documentation…"
#        (interactive …)
#        body…)
#    < src..
   ..src > elisp
     (defun append-to-buffer (buffer start end)
       "documentacion…"
       (interactive …)
       cuerpo…)
   < src..

#    The first line of the function includes its name and three arguments. The
#    arguments are the @c{buffer} to which the text will be copied, and the
#    @c{start} and @c{end} of the region in the current buffer that will be
#    copied.
   La primer línea de la función incluye su nombre y tres argumentos. Los
   argumentos son el @c{buffer} al cual copiar el texto, @c{start} y @c{end}
   que son el inicio y el fin de la región del búfer actual que se
   va a copiar.

#    The next part of the function is the documentation, which is clear and
#    complete. As is conventional, the three arguments are written in upper
#    case so you will notice them easily. Even better, they are described in
#    the same order as in the argument list.
   La siguiente parte de la función es la documentación, que es clara y
   completa. Como es convencional, los tres argumentos se escriben en
   mayúsculas para que los notes con facilidad. Aun mejor, se describen en el
   mismo orden que en la lista de argumentos.

#    Note that the documentation distinguishes between a buffer and its name.
#    (The function can handle either.)
   Observa que la documentación distingue entre un búfer y su nombre. (La
   función puede manejar cualquiera.)

# *** The @c{append-to-buffer} Interactive Expression
*** La expresión interactiva @c{append-to-buffer}

#     Since the @c{append-to-buffer} function will be used interactively, the
#     function must have an @c{interactive} expression.  (For a review of
#     @c{interactive}, see Section @l{#Make a Function Interactive}.) The
#     expression reads as follows:
    Ya que la función @c{append-to-buffer} se puede utilizar de forma
    interactiva, la función debe tener una expresión @c{interactive}. (Para
    una analisis de @c{interactive}, consulta la seccion @l{#Crear una función
    interactiva}.)  La expresión se lee de la siguiente manera:

#     ..src > elisp
#       (interactive
#        (list (read-buffer
#               "Append to buffer: "
#               (other-buffer (current-buffer) t))
#              (region-beginning)
#              (region-end)))
#     < src..
    ..src > elisp
      (interactive
       (list (read-buffer
              "Agregar al buffer: "
              (other-buffer (current-buffer) t))
             (region-beginning)
             (region-end)))
    < src..

#     This expression is not one with letters standing for parts, as described
#     earlier. Instead, it starts a list with these parts:
    Esta expresión no tiene letras que representen partes, como se describio
    anteriormente. En su lugar, inicia una lista con estas partes:

#     The first part of the list is an expression to read the name of a buffer
#     and return it as a string. That is @c{read-buffer}. The function
#     requires a prompt as its first argument, @'{"Append to buffer: "}. Its
#     second argument tells the command what value to provide if you don't
#     specify anything.
    La primer parte de la lista es una expresión para leer el nombre de un
    búfer y devolverlo como una cadena. Es decir @c(read-buffer). La función
    requiere un prompt como primer argumento, @'{"Agregar al buffer: "}. El
    segundo argumento le indica al comando que valor proporcionar si no se
    especifica nada.

#     In this case that second argument is an expression containing the
#     function @c{other-buffer}, an exception, and a @'{t}, standing for true.
    En este caso ese segundo argumento es una expresión que contiene la
    función @c{other-buffer}, una excepción, y una @'{t}, que significa
    verdadero.

#     The first argument to @c{other-buffer}, the exception, is yet another
#     function, @c{current-buffer}. That is not going to be returned. The
#     second argument is the symbol for true, @c{t}. that tells
#     @c{other-buffer} that it may show visible buffers (except in this case,
#     it will not show the current buffer, which makes sense).
    El primer argumento de @c{other-buffer}, la excepción, es otra función,
    @c{current-buffer}. Esto no va a ser devuelto. El segundo argumento es el
    símbolo de verdadero, @c{t}. Que le dice a @c{other-buffer} que puede
    mostrar búfers visibles (excepto en este caso, que no mostrará el búfer
    actual, lo cual tiene sentido).

#     The expression looks like this:
    La expresión se ve asi:

#     ..src > elisp
#       (other-buffer (current-buffer) t)
#     < src..
    ..src > elisp
      (other-buffer (current-buffer) t)
    < src..

#     The second and third arguments to the @c{list} expression are
#     @c{(region-beginning)} and @c{(region-end)}. These two functions specify
#     the beginning and end of the text to be appended.
    El segundo y tercer argumento de la expresión @c{list} son
    @c{(region-beginning)} y @c{(region-end)}. Estas dos funciones
    especifican el inicio y el final del texto a añadir.

#     Originally, the command used the letters @'{B} and @'{r}. The whole
#     @c{interactive} expression looked like this:
    Originalmente, el comando utilizaba las letras @'{B} y @'{r}. Toda la
    expresión @c{interactive} se veia así:

#     ..src > elisp
#       (interactive "BAppend to buffer: \nr")
#     < src..
    ..src > elisp
      (interactive "BAppend to buffer: \nr")
    < src..

#     But when that was done, the default value of the buffer switched to was
#     invisible. That was not wanted.
    Pero cuando se hacia esto, el valor por defecto del búfer de cambió era
    invisible. Esto no era lo que se queria.

#     (The prompt was separated from the second argument with a newline,
#     @'{\n}. It was followed by an @'{r} that told Emacs to bind the two
#     arguments that follow the symbol @c{buffer} in the function's argument
#     list (that is, @c{start} and @c{end}) to the values of point and mark.
#     That argument worked fine.)
    (El prompt se separo del segundo argumento con una línea nueva,
    @'{\n}. Seguido por un @'{r} que le indica a Emacs unir los dos
    argumentos que siguen al símbolo @c{buffer} en la lista de argumentos de
    la función (es decir, @c{start} y @c{end}) a los valores del punto y
    marca. Este argumento funcionaba bien.)

# *** The Body of @c{append-to-buffer}
*** El cuerpo de @c{append-to-buffer}

#     The body of the @c{append-to-buffer} function begins with @c{let}.
    El cuerpo de la función @c{append-to-buffer} inicia con @c{let}.

#     As we have seen before (see Section @l(#c{let}), the purpose of a @c{let}
#     expression is to create and give initial values to one or more
#     variables that will only be used within the body of the @c{let}. This
#     means that such a variable will not be confused with any variable of
#     the same name outside the @c{let} expression.
    Como hemos visto antes (Seccion @l{#@c(let)}), el propósito de una
    expresión @c{let} es crear y dar valores iniciales a una o más variables que
    solo se usaran dentro del cuerpo del @c{let}. Esto significa que esa
    variable no se confundira con ninguna variable del mismo nombre fuera
    de la expresión @c{let}.

#     We can see how the @c{let} expression fits into the function as a whole
#     by showing a template for @c{append-to-buffer} with the @c{let}
#     expression in outline:
    Podemos ver como la expresión @c{let} encaja en la función como un todo
    mostrando una plantilla de @c{append-to-buffer} con la expresión @c{let}
    en el esquema:

#     ..src > elisp
#       (defun append-to-buffer (buffer start end)
#         "documentation…"
#         (interactive …)
#         (let ((variable value))
#               body…)
#     < src..
    ..src > elisp
      (defun append-to-buffer (buffer start end)
        "documentacion…"
        (interactive …)
        (let ((variable valor))
              cuerpo…)
    < src..

#     The @c{let} expression has three elements:
    La expresión @c{let} tiene tres elementos:

#     1. The symbol @c{let};
    1. El símbolo @c{let};

#     2. A varlist containing, in this case, a single two-element list,
#        @c{(variable value)};
    2. Una varlist que contiene, en este caso, una unica lista de dos
       elementos, @c{(variable valor)};

#     3. The body of the @c{let} expression.
    3. El cuerpo de la expresión @c{let}.


#     In the @c{append-to-buffer} function, the varlist looks like this:
    En la función @c{append-to-buffer}, la varlist es la siguiente:

#     ..src > elisp
#       (oldbuf (current-buffer))
#     < src..
    ..src > elisp
      (oldbuf (current-buffer))
    < src..

#     In this part of the @c{let} expression, the one variable, @c{oldbuf}, is
#     bound to the value returned by the @c{(current-buffer)} expression. The
#     variable, @c{oldbuf}, is used to keep track of the buffer in which you
#     are working and from which you will copy.
    En esta parte de la expresión @c{let}, la unica variable, @c{oldbuf} se
    liga al valor devuelto por la expresión @c{(current-buffer)}. La variable,
    @c{oldbuf}, se utiliza para guardar un registro del búfer en el que se
    está trabajando y desde el que se va a copiar.

#     The element or elements of a varlist are surrounded by a set of
#     parentheses so the Lisp interpreter can distinguish the varlist from the
#     body of the @c{let}. As a consequence, the two-element list within the
#     varlist is surrounded by a circumscribing set of parentheses. The line
#     looks like this:
    El elemento o elementos de una varlist estan rodeados por un conjunto de
    paréntesis por lo que el intérprete Lisp puede distinguir la varlist del
    cuerpo del @c{let}. Como consecuencia, la lista de dos elementos dentro
    de la varlist está rodeada por un conjunto circunscrito de paréntesis.
    La línea tiene este aspecto:

#     ..src > elisp
#       (let ((oldbuf (current-buffer)))
#         … )
#     < src..
    ..src > elisp
      (let ((oldbuf (current-buffer)))
        … )
    < src..

#     The two parentheses before @c{oldbuf} might surprise you if you did not
#     realize that the first parenthesis before @c{oldbuf} marks the boundary
#     of the varlist and the second parenthesis marks the beginning of the
#     two-element list, @c{(oldbuf (current-buffer))}.
    Los dos paréntesis antes de @c{oldbuf} podrían sorprenderte si no fuera
    porque el primer paréntesis marca el límite de la varlist y el segundo
    paréntesis marca el inicio de la lista de dos elementos, @c{(oldbuf
    (current-buffer))}.

# *** @c{save-excursion} in @c{append-to-buffer}
*** @c{save-excursion} en @c{append-to-buffer}

#     The body of the @c{let} expression in @c{append-to-buffer} consists of a
#     @c{save-excursion} expression.
    El cuerpo de la expresión @c{let} dentro de @c{append-to-buffer} consiste
    en una expresión @c{save-excursion}.

#     The @c{save-excursion} function saves the locations of point and mark,
#     and restores them to those positions after the expressions in the body of
#     the @c{save-excursion} complete execution. In addition,
#     @c{save-excursion} keeps track of the original buffer, and restores it.
#     This is how @c{save-excursion} is used in @c{append-to-buffer}.
    La función @c{save-excursion} guarda las posiciones de punto y marca, y
    restaura estas posiciones después de que las expresiones en el cuerpo de
    @c{save-excursion} completan su ejecución. Además, @c{save-excursion} no
    pierde de vista el búfer original, y lo restaura. Asi es como se utiliza
    @c{save-excursion} en @c{append-to-buffer}.

#     Incidentally, it is worth noting here that a Lisp function is normally
#     formatted so that everything that is enclosed in a multi-line spread is
#     indented more to the right than the first symbol. In this function
#     definition, the @c{let} is indented more than the @c{defun}, and the
#     @c{save-excursion} is indented more than the @c{let}, like this:
    Por cierto, vale la pena señalar que una función Lisp normalmente se
    formatea de modo que todo lo que esta encerrado en un conjunto de multiples
    lineas se indente más a la derecha que el primer símbolo. En esta
    definición de función, @c{let} se indenta más que @c{defun}, y
    @c{save-excursion} se indenta más que @c{let} y asi sucesivamente:

#     ..src > elisp
#       (defun …
#         …
#         …
#         (let…
#           (save-excursion
#             …
#     < src..
    ..src > elisp
      (defun …
        …
        …
        (let…
          (save-excursion
            …
    < src..

#     This formatting convention makes it easy to see that the lines in the
#     body of the @c{save-excursion} are enclosed by the parentheses associated
#     with @c{save-excursion}, just as the @c{save-excursion} itself is
#     enclosed by the parentheses associated with the @c{let}:
    Esta convención de formato hace que sea fácil ver que líneas en el
    cuerpo de @c{save-excursion} estan rodeadas por los parentesis asociados
    con @c{save-excursion}, de la misma manera que @c(save-excursion) esta
    rodeada por los paréntesis asociados con @c{let}:

#     ..src > elisp
#       (let ((oldbuf (current-buffer)))
#         (save-excursion
#           …
#           (set-buffer …)
#           (insert-buffer-substring oldbuf start end)
#           …))
#     < src..
    ..src > elisp
      (let ((oldbuf (current-buffer)))
        (save-excursion
          …
          (set-buffer …)
          (insert-buffer-substring oldbuf start end)
          …))
    < src..

#     The use of the @c{save-excursion} function can be viewed as a process of
#     filling in the slots of a template:
    El uso de la función @c{save-excursion} puede verse como un proceso de
    rellenar las ranuras de una plantilla:

#     ..src > elisp
#       (save-excursion
#         first-expression-in-body
#         second-expression-in-body
#          …
#         last-expression-in-body)
#     < src..
    ..src > elisp
      (save-excursion
        primer-expresion-en-el-cuerpo
        segunda-expresion-en-el-cuerpo
         …
        ultima-expresion-en-el-cuerpo)
    < src..

#     In this function, the body of the @c{save-excursion} contains only one
#     expression, the @c{let*} expression. You know about a @c{let} function.
#     The @c{let*} function is different. It has a @'{*} in its name. It
#     enables Emacs to set each variable in its varlist in sequence, one after
#     another.
    En esta función, el cuerpo de @c{save-excursion} contiene solo una
    expresión, la expresión @c{let*}. Ya conoces la función @c{let}. La
    función @c{let*} es diferente. Posee un @'{*} en su nombre. Esto le
    permite a Emacs colocar cada variable de su varlist en secuencia, una
    después de otra.

#     Its critical feature is that variables later in the varlist can make use
#     of the values to which Emacs set variables earlier in the varlist. See
#     Section @l{#The @c{let*} expression}.
    Su caracteristica fundamental es que las siguientes variables en la
    varlist puedan hacer uso de los valores establecidos por Emacs
    anteriormente en la varlist. Consulta la Seccion @l{#La expresión @c{let*}}.

#     We will skip functions like @c{let*} and focus on two: the @c{set-buffer}
#     function and the @c{insert-buffer-substring} function.
    Vamos a omitir funciones como @c{let*} y nos centraremos en dos: la
    función @c{set-buffer} y la función @c{insert-buffer-substring}.

#     In the old days, the @c{set-buffer} expression was simply
    En los viejos tiempos, la expresión @c{set-buffer} era simplemente:

#     ..src > elisp
#       (set-buffer (get-buffer-create buffer))
#     < src..
    ..src > elisp
      (set-buffer (get-buffer-create buffer))
    < src..

#     but now it is
    pero ahora es

#     ..src > elisp
#       (set-buffer append-to)
#     < src..
    ..src > elisp
      (set-buffer append-to)
    < src..

#     @c{append-to} is bound to @c{(get-buffer-create buffer)} earlier on in
#     the @c{let*} expression. That extra binding would not be necessary
#     except for that @c{append-to} is used later in the varlist as an argument
#     to @c{get-buffer-window-list}.
    @c{append-to} esta ligado al @c{(get-buffer-create-buffer)} anterior en la
    expresión @c{let*}. Esta union extra no sería necesaria excepto que
    @c{append-to} se utiliza despues en la varlist como un argumento para
    @c{get-buffer-window-list}.

#     The @c{append-to-buffer} function definition inserts text from the buffer
#     in which you are currently to a named buffer. It happens that
#     @c{insert-buffer-substring} copies text from another buffer to the
#     current buffer, just the reverse––that is why the @c{append-to-buffer}
#     definition starts out with a @c{let} that binds the local symbol
#     @c{oldbuf} to the value returned by @c{current-buffer}.
    La definición de la función @c{append-to-buffer} inserta texto desde el
    búfer en el que te encuentras actualmente al buffer que se indique. Sucede
    que @c{insert-buffer-substring} copia texto desde otro búfer al búfer
    actual, justo al reves––es por ello que la definición @c{append-to-buffer}
    inicia con un @c{let} que une el símbolo local @c{oldbuf} al valor devuelto
    por @c{current-buffer}.

#     The @c{insert-buffer-substring} expression looks like this:
    La expresión @c{insert-buffer-substring} es la siguiente:

#     ..src > elisp
#       (insert-buffer-substring oldbuf start end)
#     < src..
    ..src > elisp
      (insert-buffer-substring oldbuf start end)
    < src..

#     The @c{insert-buffer-substring} function copies a string @e{from} the
#     buffer specified as its first argument and inserts the string into the
#     present buffer. In this case, the argument to
#     @c{insert-buffer-substring} is the value of the variable created and
#     bound by the @c{let}, namely the value of @c{oldbuf}, which was the
#     current buffer when you gave the @c{append-to-buffer} command.
    La función @c{insert-buffer-substring} copia una cadena @e{desde} el
    búfer especificado como su primer argumento e inserta la cadena dentro
    del búfer actual. En este caso, el argumento de @c{insert-buffer-substring}
    es el valor de la variable creada y vinculada por @c{let}, es decir, el
    valor de @c{oldbuf}, que era el búfer actual cuando se dio el comando
    @c{append-to-buffer}.

#     After @c{insert-buffer-substring} has done its work, @c{save-excursion}
#     will restore the action to the original buffer and @c{append-to-buffer}
#     will have done its job.
    Después de que @c{insert-buffer-substring} ha hecho su trabajo,
    @c{save-excursion} restaurará la acción al búfer original y
    @c{append-to-buffer} habrá hecho su trabajo.

#     Written in skeletal form, the workings of the body look like this:
    Escrito en forma esqueletal, los funcionamientos del cuerpo se ven asi:

#     ..src > elisp
    ..src > elisp
#       (let (bind-oldbuf-to-value-of-current-buffer)
#         (save-excursion                       ; Keep track of buffer.
#           change-buffer
#           insert-substring-from-oldbuf-into-buffer)
      (let (unir-oldbuf-al-valor-del-buffer-actual)
        (save-excursion                       ; guarda un registro del buffer.
          cambio-de-buffer
          insertar-subcadena-desde-oldbuf-a-buffer)

#         change-back-to-original-buffer-when-finished
#       let-the-local-meaning-of-oldbuf-disappear-when-finished
        regresar-al-buffer-original-al-terminar
      dejar-que-el-siginificado-local-de-oldbuf-desaparacesca-al-terminar
#     < src..
    < src..

#     In summary, @c{append-to-buffer} works as follows: it saves the value of
#     the current buffer in the variable called @c{oldbuf}. It gets the new
#     buffer (creating one if need be) and switches Emacs's attention to it.
#     Using the value of @c{oldbuf}, it inserts the region of text from the old
#     buffer into the new buffer; and then using @c{save-excursion}, it brings
#     you back to your original buffer.
    En resumen, @c{append-to-buffer} funciona de la siguiente manera: guarda el
    valor del búfer actual en la variable @c{oldbuf}. Obtiene el nuevo búfer
    (creando uno si es necesario) y cambia la atención de Emacs a este. Usando
    el valor de @c{oldbuf}, inserta la región del texto desde el búfer antiguo
    dentro del nuevo búfer; y luego usando @c{save-excursion}, regresa al búfer
    original.

#     In looking at @c{append-to-buffer}, you have explored a fairly complex
#     function. It shows how to use @c{let} and @c{save-excursion}, and how to
#     change to and come back from another buffer. Many function definitions
#     use @c{let}, @c{save-excursion}, and @c{set-buffer} this way.
    Al observar @c{append-to-buffer}, se ha explorado una función bastante
    compleja. Muestra como usar @c{let} y @c{save-excursion}, y como cambiar
    y volver desde otro buffer. Muchas definiciones de función usan @c{let},
    @c{save-excursion}, y @c{set-buffer} de esta manera.

# ** Review
** Repaso

#    Here is a brief summary of the various functions discussed in this
#    chapter.
   Aquí está un breve resumen de las diferentes funciones descritas en este
   capítulo.

#    - @c(describe-function), @c(describe-variable) ::
   - @c(describe-function), @c(describe-variable) ::

#      Print the documentation for a function or variable. Conventionally
#      bound to @k{C-h f} and @k{C-h v}.
     Imprimen la documentación de una función o variable. Convencionalmente
     unidas a @k{C-h f} y @k{C-h v}.

#    - @c(find-tag) ::
   - @c(find-tag) ::

#      Find the file containing the source for a function or variable and
#      switch buffers to it, positioning point at the beginning of the item.
#      Conventionally bound to @k{M-.} (that's a period following the @k{META}
#      key).
     Encuentra el fichero que contiene el codigo de una función o variable y
     cambia a dicho buffer, colocando el punto al inicio del elemento.
     Convencionalmente ligado a @k{M-.} (esto es un punto luego de la tecla
     @k{META}).

#    - @c(save-excursion) ::
   - @c(save-excursion) ::

#      Save the location of point and mark and restore their values after the
#      arguments to @c{save-excursion} have been evaluated. Also, remember the
#      current buffer and return to it.
     Guarda la posicion de punto y marca y restaura sus valores tras evaluar
     los argumentos de @c{save-excursion}. Ademas, recuerda el buffer actual
     y regresa a el.

#    - @c(push-mark) ::
   - @c(push-mark) ::

#      Set mark at a location and record the value of the previous mark on the
#      mark ring. The mark is a location in the buffer that will keep its
#      relative position even if text is added to or removed from the buffer.
     Establece la marca a una posicion y registra el valor de la marca anterior en
     el anillo de marcas. La marca es una ubicacion en el búfer que
     mantendra su posición relativa, incluso si se añade o borra texto del
     búfer.

#    - @c(goto-char) ::
   - @c(goto-char) ::

#      Set point to the location specified by the value of the argument, which
#      can be a number, a marker, or an expression that returns the number of a
#      position, such as @c{(point-min)}.
     Establece el punto a la ubicacion especificada por el valor del
     argumento, que puede ser un número, una marca, o una expresión que
     devuelve el número de una posición, como @c{(point-min)}.

#    - @c(insert-buffer-substring) ::
   - @c(insert-buffer-substring) ::

#      Copy a region of text from a buffer that is passed to the function as an
#      argument and insert the region into the current buffer.
     Copia una región de texto desde un búfer que se pasa a la función como
     argumento e inserta la región dentro del búfer actual.

#    - @c(mark-whole-buffer) ::
   - @c(mark-whole-buffer) ::

#      Mark the whole buffer as a region. Normally bound to @k{C-x h}.
     Marca el búfer completo como una región. Normalmente unido a @k{C-x h}.

#    - @c(set-buffer) ::
   - @c(set-buffer) ::

#      Switch the attention of Emacs to another buffer, but do not change the
#      window being displayed. Used when the program rather than a human is to
#      work on a different buffer.
     Cambia la atención de Emacs a otro búfer, pero no se muestra el cambio
     en la ventana. Se utiliza cuando un programa y no un humano trabaja en un
     búfer distinto.

#    - @c(get-buffer-create), @c(get-buffer) ::
   - @c(get-buffer-create), @c(get-buffer) ::

#      Find a named buffer or create one if a buffer of that name does not
#      exist. The @c{get-buffer} function returns @c{nil} if the named buffer
#      does not exist.
     Busca un búfer con nombre o crea uno si el búfer con ese nombre no
     existe. La función @c{get-buffer} devuelve @c{nil} si el nombre del
     búfer no existe.

# ** Exercises
** Ejercicios

#    - Write your own @c{simplified-end-of-buffer} function definition; then
#      test it to see whether it works.
   - Escribe tu propia definición de la función @c{end-of-buffer-simplicifado};
     luego pruebala para ver si funciona.

#    - Use @c{if} and @c{get-buffer} to write a function that prints a message
#      telling you whether a buffer exists.
   - Utiliza @c{if} y @c{get-buffer} para escribir una función que imprima un
     mensaje que indique si un buffer existe.

#    - Using @c{find-tag}, find the source for the @c{copy-to-buffer} function.
   - Usando @c{find-tag}, busca el codigo de la función @c{copy-to-buffer}

# * A Few More Complex Functions
* Algunas Funciones Más Complejas

#   In this chapter, we build on what we have learned in previous chapters by
#   looking at more complex functions. The @c{copy-to-buffer} function
#   illustrates use of two @c{save-excursion} expressions in one definition,
#   while the @c{insert-buffer} function illustrates use of an asterisk in an
#   @c{interactive} expression, use of @c{or}, and the important distinction
#   between a name and the object to which the name refers.
  En este capítulo, nos basamos en lo que hemos aprendido en los capítulos
  anteriores al analizar funciones más complejas. La función @c{copy-to-buffer}
  ilustra el uso de dos expresiones @c{save-excursion} en una definición,
  mientras que la función @c{insert-buffer} ilustra el uso de un asterisco en
  una expresión @c{interactive}, el uso de @c{or}, y la importante distinción
  entre un nombre y el objeto al que el nombre hace referencia.

# ** The Definition of @c{copy-to-buffer}
** La definición de @c{copy-to-buffer}

#    After understanding how @c{append-to-buffer} works, it is easy to
#    understand @c{copy-to-buffer}. This function copies text into a buffer,
#    but instead of adding to the second buffer, it replaces all the previous
#    text in the second buffer.
   Después de comprender cómo trabaja @c{append-to-buffer}, es fácil entender
   @c{copy-to-buffer}. Esta función copia texto dentro de un búfer, pero en
   lugar de agregarlo al segundo búfer, sustituye todo el texto en el segundo
   búfer.

#    The body of @c{copy-to-buffer} looks like this,
   El cuerpo de @c{copy-to-buffer} tiene este aspecto,

#    ..src > elisp
#      …
#      (interactive "BCopy to buffer: \nr")
#      (let ((oldbuf (current-buffer)))
#        (with-current-buffer (get-buffer-create buffer)
#          (barf-if-buffer-read-only)
#          (erase-buffer)
#          (save-excursion
#            (insert-buffer-substring oldbuf start end)))))
#    < src..
   ..src > elisp
     …
     (interactive "BCopy to buffer: \nr")
     (let ((oldbuf (current-buffer)))
       (with-current-buffer (get-buffer-create buffer)
         (barf-if-buffer-read-only)
         (erase-buffer)
         (save-excursion
           (insert-buffer-substring oldbuf start end)))))
   < src..

#    The @c{copy-to-buffer} function has a simpler @c{interactive} expression
#    than @c{append-to-buffer}.
   La función @c{copy-to-buffer} tiene una expresión @c{interactive} mas
   sencilla que @c{append-to-buffer}.

#    The definition then says
   La definición dice:

#    ..src > elisp
#      (with-current-buffer (get-buffer-create buffer) …
#    < src..
   ..src > elisp
     (with-current-buffer (get-buffer-create buffer) …
   < src..

#    First, look at the earliest inner expression; that is evaluated first.
#    That expression starts with @c{get-buffer-create buffer}. The function
#    tells the computer to use the buffer with the name specified as the one to
#    which you are copying, or if such a buffer does not exist, to create it.
#    Then, the @c{with-current-buffer} function evaluates its body with that
#    buffer temporarily current.
   En primer lugar, mira la expresión más interna; que se evalua primero.
   Esta expresión inicia con @c{get-buffer-create buffer}. La función le indica
   al ordenador que utilice el búfer con el nombre específicado como aquel que
   quieres copiar, o si tal búfer no existe, que lo cree. Luego, la función
   @c{with-current-buffer} evalúa su cuerpo con este búfer temporal.

#    (This demonstrates another way to shift the computer's attention but not
#    the user's. The @c{append-to-buffer} function showed how to do the same
#    with @c{save-excursion} and @c{set-buffer}.  @c{with-current-buffer} is a
#    newer, and arguably easier, mechanism.)
   (Esto demuestra otra forma de cambiar la atención del ordenador pero no
   la del usuario. La función @c{append-to-buffer} muestro como hacer lo
   mismo con @c{save-excursion} y @c{set-buffer}. @c{with-current-buffer} es un
   mecanismo nuevo, y posiblemente mas sencillo.)

#    The @c{barf-if-buffer-read-only} function sends you an error message
#    saying the buffer is read-only if you cannot modify it.
   La función @c{barf-if-buffer-read-only} envía un mensaje de error diciendo
   que el búfer es de solo lectura si no se puede modificar.

#    The next line has the @c{erase-buffer} function as its sole contents.
#    That function erases the buffer.
   La siguiente línea tiene como único contenido la función
   @c{erase-buffer}. Este función borra el búfer.

#    Finally, the last two lines contain the @c{save-excursion} expression with
#    @c{insert-buffer-substring} as its body. The @c{insert-buffer-substring}
#    expression copies the text from the buffer you are in (and you have not
#    seen the computer shift its attention, so you don't know that that buffer
#    is now called @c{oldbuf}).
   Finalmente, las últimas dos líneas contienen la expresión @c{save-excursion}
   con @c{insert-buffer-substring} como cuerpo. La expresión
   @c{insert-buffer-substring} copia el texto desde el búfer en el que te
   encuentras (y no has visto al ordenador cambiar su atención, por lo que no
   sabes que ese búfer ahora se llama @c{oldbuf}).

#    Incidentally, this is what is meant by ‘replacement’. To replace text,
#    Emacs erases the previous text and then inserts new text.
   Por cierto, esto es lo que se entiende por ‘reemplazo’. Para reemplazar el
   texto Emacs borra el texto anterior y luego inserta un texto nuevo.

#    In outline, the body of @c{copy-to-buffer} looks like this:
   A grandes rasgos, el cuerpo de @c{copy-to-buffer} se ve asi:

#    ..src > elisp
#      (let (bind-oldbuf-to-value-of-current-buffer)
#          (with-the-buffer-you-are-copying-to
#            (but-do-not-erase-or-copy-to-a-read-only-buffer)
#            (erase-buffer)
#            (save-excursion
#              insert-substring-from-oldbuf-into-buffer)))
#    < src..
   ..src > elisp
     (let (enlazar-oldbuf-al-valor-del-bufer-actual)
         (con-el-bufer-al-que-estas-copiando
           (pero-no-borrar-o-copiar-a-un-bufer-de-solo-lectura)
           (erase-buffer)
           (save-excursion
             insertar-la-subcadena-desde-oldbuf-en-el-bufer)))
   < src..

# ** The Definition of @c{insert-buffer}
** La definición de @c{insert-buffer}

#    @c{insert-buffer} is yet another buffer-related function. This command
#    copies another buffer @e{into} the current buffer. It is the reverse of
#    @c{append-to-buffer} or @c{copy-to-buffer}, since they copy a region of
#    text @e{from} the current buffer to another buffer.
   @c{insert-buffer} es otra función relacionada con búfers. Este comando copia
   otro búfer @e{dentro} del búfer actual. Es lo contrario a @c{append-to-buffer}
   o @c{copy-to-buffer}, dado que copia una región de texto @e{desde} el búfer
   actual a otro búfer.

#    Here is a discussion based on the original code. The code was simplified
#    in 2003 and is harder to understand.
   Aquí examinamos en el código original. El código se simplifico en 2003 y
   es mas dificil de entender.

#    (See Section @l{#New Body for @c{insert-buffer}}, to see a discussion of
#    the new body.)
   (Consulta la Seccion @l{#Nuevo Cuerpo para @c{insert-buffer}}, para ver una
   discusión del nuevo cuerpo.)

#    In addition, this code illustrates the use of @c{interactive} with a
#    buffer that might be @:{read-only} and the important distinction between
#    the name of an object and the object actually referred to.
   Además, este código ilustra el uso de @c{interactive} con un búfer que
   podría ser @:{read-only} @%i(de solo lectura) y la importante distinción entre
   el nombre de un objeto y el objeto al que realmente hace referencia.

#    Here is the earlier code:
   Aquí está el código anterior:

#    ..src > elisp
#      (defun insert-buffer (buffer)
#        "Insert after point the contents of BUFFER.
#      Puts mark after the inserted text.
#      BUFFER may be a buffer or a buffer name."
#        (interactive "*bInsert buffer: ")
#        (or (bufferp buffer)
#            (setq buffer (get-buffer buffer)))
#        (let (start end newmark)
#          (save-excursion
#            (save-excursion
#              (set-buffer buffer)
#              (setq start (point-min) end (point-max)))
#            (insert-buffer-substring buffer start end)
#            (setq newmark (point)))
#          (push-mark newmark)))
#    < src..
   ..src > elisp
     (defun insert-buffer (buffer)
       "Insertar despues del punto el contenido de BUFFER.
     Coloca la marca despues del texto insertado.
     BUFFER puede ser un buffer o el nombre de un buffer."
       (interactive "*bInsert buffer: ")
       (or (bufferp buffer)
           (setq buffer (get-buffer buffer)))
       (let (start end newmark)
         (save-excursion
           (save-excursion
             (set-buffer buffer)
             (setq start (point-min) end (point-max)))
           (insert-buffer-substring buffer start end)
           (setq newmark (point)))
         (push-mark newmark)))
   < src..

#    As with other function definitions, you can use a template to see an
#    outline of the function:
   Al igual que con otras definiciones de función, se puede usar una plantilla
   para ver un esquema de la función:

#    ..src > elisp
#      (defun insert-buffer (buffer)
#        "documentation…"
#        (interactive "*bInsert buffer: ")
#        body…)
#    < src..
   ..src > elisp
     (defun insert-buffer (buffer)
       "documentacion…"
       (interactive "*bInsert buffer: ")
       cuerpo…)
   < src..

# *** The Interactive Expression in @c{insert-buffer}
*** La expresión interactiva en @c{insert-buffer}

#     In @c{insert-buffer}, the argument to the @c{interactive} declaration has
#     two parts, an asterisk, @'c{*}, and @'c{bInsert buffer: }.
    En @c{insert-buffer}, el argumento de la declaración @c{interactive} tiene
    dos partes, un asterisco, @'c{*}, y @'c{bInsert buffer: }.

# **** A Read-only Buffer
**** Un búfer de solo lectura

#      The asterisk is for the situation when the current buffer is a read-only
#      buffer––a buffer that cannot be modified. If @c{insert-buffer} is
#      called when the current buffer is read-only, a message to this effect is
#      printed in the echo area and the terminal may beep or blink at you; you
#      will not be permitted to insert anything into current buffer. The
#      asterisk does not need to be followed by a newline to separate it from
#      the next argument.
     El asterisco se utliza cuando el búfer actual es un búfer de solo
     lectura––un búfer que no se puede modificar. Si se llama a
     @c{insert-buffer} cuando el búfer actual es de solo lectura, se imprime un
     mensaje en el area de eco y el terminal puede emitir un beep o parpadear;
     no se permitira insertar nada en el búfer actual. El asterisco no tiene que
     ser seguido por un salto de linea para separarlo del siguiente argumento.

# **** @'c{b} in an Interactive Expression
**** @'c{b} en una expresión interactiva

#      The next argument in the interactive expression starts with a lower case
#      @'c{b}.  (This is different from the code for @c{append-to-buffer}, which
#      uses an upper-case @'c{B}. See Section @l{#The Definition of
#      @c{append-to-buffer}}.)  The lower-case @'c{b} tells the Lisp interpreter
#      that the argument for @c{insert-buffer} should be an existing buffer or
#      else its name.  (The upper-case @'c{B} option provides for the
#      possibility that the buffer does not exist.)  Emacs will prompt you for
#      the name of the buffer, offering you a default buffer, with name
#      completion enabled. If the buffer does not exist, you receive a message
#      that says “No match”; your terminal may beep at you as well.
     El siguiente argumento de la expresión interactiva inicia con una letra
     @'c{b} minúscula. (Esto es diferente del código para @c{append-to-buffer},
     que utiliza una @'c{B} mayúscula. Consulta la Seccion @l{#La Definición de
     @c{append-to-buffer}}.) La @'c{b} minúscula le indica al intérprete Lisp que
     el argumento de @c{insert-buffer} debe ser un buffer existente o su
     nombre. (La opcion @'c{B} mayúscula permite la posibilidad de que el búfer no
     exista.) Emacs te pedira el nombre del búfer, ofreciendo un búfer por
     defecto, con el autocompletado de nombre habilitado. Si el búfer no existe,
     recibiras un mensaje que dice “No match” @%i"(no concuerda); tu terminal
     tambien puede emitir un beep.

#      The new and simplified code generates a list for @c{interactive}. It
#      uses the @c{barf-if-buffer-read-only} and @c{read-buffer} functions with
#      which we are already familiar and the @c{progn} special form with which
#      we are not.  (It will be described later.)
     El nuevo código simplificado genera una lista para @c{interactive}. Este
     utiliza las funciones @c{barf-if-buffer-read-only} y @c{read-buffer} con
     las que ya estamos familiarizados y la forma especial @c{progn} con la que
     no lo estamos. (Se describira mas adelante).

# *** The Body of the @c{insert-buffer} Function
*** El cuerpo de la función @c{insert-buffer}

#     The body of the @c{insert-buffer} function has two major parts: an @c{or}
#     expression and a @c{let} expression. The purpose of the @c{or}
#     expression is to ensure that the argument @c{buffer} is bound to a buffer
#     and not just the name of a buffer. The body of the @c{let} expression
#     contains the code which copies the other buffer into the current buffer.
    El cuerpo de la función @c{insert-buffer} tiene dos partes principales: una
    expresión @c{or} y una expresión @c{let}. El propósito de la expresión
    @c{or} es asegurar que el argumento @c{buffer} esta ligado a un búfer y no
    solo al nombre de un búfer. El cuerpo de la expresión @c{let} contiene
    el código que copia el otro búfer dentro del búfer actual.

#     In outline, the two expressions fit into the @c{insert-buffer} function
#     like this:
    A grades rasgos, las dos expresiones encajan asi en la función @c{insert-buffer}:

#     ..src > elisp
#       (defun insert-buffer (buffer)
#         "documentation…"
#         (interactive "*bInsert buffer: ")
#         (or …
#             …
#         (let (varlist)
#             body-of-let… )
#     < src..
    ..src > elisp
      (defun insert-buffer (buffer)
        "documentacion…"
        (interactive "*bInsert buffer: ")
        (or …
            …
        (let (varlist)
            cuerpo-de-let… )
    < src..

#     To understand how the @c{or} expression ensures that the argument
#     @c{buffer} is bound to a buffer and not to the name of a buffer, it is
#     first necessary to understand the @c{or} function.
    Para entender como la expresión @c{or} asegura que el argumento @c{buffer}
    esta unido a un búfer y no al nombre de un búfer, primero es necesario
    entender la función @c{or}.

#     Before doing this, let me rewrite this part of the function using @c{if}
#     so that you can see what is done in a manner that will be familiar.
    Antes de hacer esto, permíteme reescribir esta parte de la función
    utilizando @c{if} de esta manera puedes ver como se hace de una manera que
    resulte familiar.

# *** @c{insert-buffer} With an @c{if} Instead of an @c{or}
*** @c{insert-buffer} con un @c{if} en lugar de un @c{or}

#     The job to be done is to make sure the value of @c{buffer} is a buffer
#     itself and not the name of a buffer. If the value is the name, then the
#     buffer itself must be got.
    El trabajo a realizar es asegurarse de que el valor de @c{buffer} sea un
    búfer en sí mismo y no el nombre de un búfer. Si el valor es el nombre, entonces
    debe optenerse el búfer en sí.

#     You can imagine yourself at a conference where an usher is wandering
#     around holding a list with your name on it and looking for you: the usher
#     is “bound” to your name, not to you; but when the usher finds you and
#     takes your arm, the usher becomes “bound” to you.
    Puedes imaginarte a tí mismo en una conferencia donde un acomodador está
    observando una lista con tu nombre en ella y mirándote: el acomodador sabe
    “asociar” tu nombre, no a tí; pero cuando el acomodador te encuentra y
    te toma el brazo, el acomodador lo “asocia” a tí.

#     In Lisp, you might describe this situation like this:
    En Lisp, se podría describir esta situación así:

#     ..src > elisp
#       (if (not (holding-on-to-guest))
#           (find-and-take-arm-of-guest))
#     < src..
    ..src > elisp
      (if (not (tomar-al-invitado))
          (encontrar-y-tomar-del-brazo-al-invitado))
    < src..

#     We want to do the same thing with a buffer––if we do not have the buffer
#     itself, we want to get it.
    Queremos hacer lo mismo con un búfer––si no tenemos el búfer en sí,
    queremos conseguirlo.

#     Using a predicate called @c{bufferp} that tells us whether we have a
#     buffer (rather than its name), we can write the code like this:
    Usando un predicado llamado @c{bufferp} que nos informa si tenemos un búfer
    (en lugar de su nombre), podemos escribir el código de esta manera:

#     ..src > elisp
#       (if (not (bufferp buffer))              ; if-part
#           (setq buffer (get-buffer buffer)))  ; then-part
#     < src..
    ..src > elisp
      (if (not (bufferp buffer))              ; parte-if
          (setq buffer (get-buffer buffer)))  ; parte-then
    < src..

#     Here, the true-or-false-test of the @c{if} expression is @c{(not (bufferp
#     buffer))}; and the then-part is the expression @c{(setq buffer
#     (get-buffer buffer))}.
    Aquí, la prueba verdadero-o-falso de la expresión @c{if} es @c{(not (bufferp
    buffer))}; y la parte @e(then) es la expresión @c{(setq buffer (get-buffer
    buffer))}.

#     In the test, the function @c{bufferp} returns true if its argument is a
#     buffer––but false if its argument is the name of the buffer.  (The last
#     character of the function name @c{bufferp} is the character @'c{p}; as we
#     saw earlier, such use of @'c{p} is a convention that indicates that the
#     function is a predicate, which is a term that means that the function
#     will determine whether some property is true or false. See Section
#     @l{#Using the Wrong Type Object as an Argument}.)
    En la prueba, la función @c{bufferp} devuelve verdadero si su argumento es un
    búfer––sino falso si el argumento es el nombre del búfer. (El último
    carácter del nombre de la función @c{bufferp} es el carácter @'c{p}; como
    vimos anteriormente, tal uso de @'c{p} es una convención que indica que la
    función es un predicado, que es un término que significa que la función
    determinará si alguna propiedad es verdadera o falsa. Consulta la Seccion
    @l(#Usando el tipo incorrecto de objeto como argumento).)

#     The function @c{not} precedes the expression @c{(bufferp buffer)}, so the
#     true-or-false-test looks like this:
    La función @c{not} precede a la expresión @c{(bufferp buffer)}, así la prueba
    verdadero-o-falso es la siguente:

#     ..src > elisp
#       (not (bufferp buffer))
#     < src..
    ..src > elisp
      (not (bufferp buffer))
    < src..

#     @c{not} is a function that returns true if its argument is false and
#     false if its argument is true. So if @c{(bufferp buffer)} returns true,
#     the @c{not} expression returns false and vice-verse: what is “not true”
#     is false and what is “not false” is true.
    @c{not} es una función que devuelve verdadero si su argumento es falso y
    falso si su argumento es verdadero. Por lo que si @c{(bufferp buffer)}
    devuelve verdadero, la expresión @c{not} devuelve falso y viceversa: lo que es
    “no verdadero” es falso y lo que es “no falso” es verdadero.

#     Using this test, the @c{if} expression works as follows: when the value
#     of the variable @c{buffer} is actually a buffer rather than its name, the
#     true-or-false-test returns false and the @c{if} expression does not
#     evaluate the then-part. This is fine, since we do not need to do
#     anything to the variable @c{buffer} if it really is a buffer.
    Usando esta prueba, la expresión @c{if} funciona de la siguiente manera:
    cuando el valor de la variable @c{buffer} es realmente un búfer en
    lugar de su nombre, la prueba verdadero-o-falso devuelve falso y la
    expresión @c{if} no evalúa la parte-then. Esto está bien, ya que no tenemos
    que hacer nada para la variable @c{buffer} si realmente es un búfer.

#     On the other hand, when the value of @c{buffer} is not a buffer itself,
#     but the name of a buffer, the true-or-false-test returns true and the
#     then-part of the expression is evaluated. In this case, the then-part is
#     @c{(setq buffer (get-buffer buffer))}. This expression uses the
#     @c{get-buffer} function to return an actual buffer itself, given its
#     name. The @c{setq} then sets the variable @c{buffer} to the value of the
#     buffer itself, replacing its previous value (which was the name of the
#     buffer).
    Por otro lado, cuando el valor de @c{buffer} no es un buffer en sí, pero si
    el nombre de un buffer, la prueba verdadero-o-falso devuelve verdadero y se
    evalua la parte-then de la expresión. En este caso, la parte-then es
    @c{(setq buffer (get-buffer buffer))}. Esta expresión utiliza la función
    @c{get-buffer} para devolver un buffer real, dado su nombre. Luego @c{setq}
    asigna la variable @c{buffer} reemplazando su valor anterior (que era el
    nombre del búfer).

# *** The @c{or} in the Body
*** El @c{or} en el cuerpo

#     The purpose of the @c{or} expression in the @c{insert-buffer} function is
#     to ensure that the argument @c{buffer} is bound to a buffer and not just
#     to the name of a buffer. The previous section shows how the job could
#     have been done using an @c{if} expression. However, the
#     @c{insert-buffer} function actually uses @c{or}. To understand this, it
#     is necessary to understand how @c{or} works.
    El propósito de la expresión @c{or} en la función @c{insert-buffer} es
    asegurar que el argumento @c{buffer} está ligado a un búfer y no solo al
    nombre de uno. La sección previa muestra como se podría haber hecho el
    trabajo usando una expresión @c{if}. Sin embargo, la función
    @c{insert-buffer} utiliza @c{or}. Para entender esto, es necesario entender
    como funciona @c{or}.

#     An @c{or} function can have any number of arguments. It evaluates each
#     argument in turn and returns the value of the first of its arguments that
#     is not @c{nil}. Also, and this is a crucial feature of @c{or}, it does
#     not evaluate any subsequent arguments after returning the first
#     non-@c{nil} value.
    Una función @c{or} puede tener cualquier número de argumentos. Evalúa
    un argumento a la ves y devuelve el valor del primero de sus argumentos que
    no es @c{nil}. Ademas, y esta es una caracteristica crucial de @c{or}, no
    evalúa ningun argumento posterior después de regresar el primer valor
    no-@c{nil}.

#     The @c{or} expression looks like this:
    La expresión @c{or} se ve asi:

#     ..src > elisp
#       (or (bufferp buffer)
#           (setq buffer (get-buffer buffer)))
#     < src..
    ..src > elisp
      (or (bufferp buffer)
          (setq buffer (get-buffer buffer)))
    < src..

#     The first argument to @c{or} is the expression @c{(bufferp buffer)}.
#     This expression returns true (a non-@c{nil} value) if the buffer is
#     actually a buffer, and not just the name of a buffer. In the @c{or}
#     expression, if this is the case, the @c{or} expression returns this true
#     value and does not evaluate the next expression––and this is fine with
#     us, since we do not want to do anything to the value of @c{buffer} if it
#     really is a buffer.
    El primer argumento de @c{or} es la expresión @c{(bufferp buffer)}. Esta
    expresión devuelve verdadero (un valor no-@c{nil}) si el búfer es realmente
    un búfer, y no solo el nombre de un búfer. En la expresión @c{or}, si este
    es el caso, la expresión @c{or} devuelve este valor verdadero y no evalúa la
    siguiente expresión––y esto esta bien para nosotros, ya que no queremos hacer
    nada con el valor de @c{buffer} si realmente es un búfer.

#     On the other hand, if the value of @c{(bufferp buffer)} is @c{nil}, which
#     it will be if the value of @c{buffer} is the name of a buffer, the Lisp
#     interpreter evaluates the next element of the @c{or} expression. This is
#     the expression @c{(setq buffer (get-buffer buffer))}. This expression
#     returns a non-@c{nil} value, which is the value to which it sets the
#     variable @c{buffer}––and this value is a buffer itself, not the name of
#     a buffer.
    Por otro lado, si el valor de @c{(bufferp buffer)} es @c{nil}, que lo sera
    si el valor de @c{buffer} es el nombre de un buffer, el intérprete Lisp
    evalúa el siguiente elemento de la expresión. Esta es la expresión @c{(setq
    buffer (get-buffer buffer))}. Esta expresión devuelve un valor no-@c{nil},
    que es el valor al que establece la variable @c{buffer}––y este valor es
    un búfer en sí, no el nombre de un búfer.

#     The result of all this is that the symbol @c{buffer} is always bound to a
#     buffer itself rather than to the name of a buffer. All this is necessary
#     because the @c{set-buffer} function in a following line only works with a
#     buffer itself, not with the name to a buffer.
    El resultado de todo esto es que el símbolo @c{buffer} siempre esta ligado a
    un búfer en sí mismo y no al nombre de uno. Todo esto es necesario
    porque la función @c{set-buffer} en la línea siguiente solo funciona
    con un buffer en sí, no con el nombre de un búfer.

#     Incidentally, using @c{or}, the situation with the usher would be written
#     like this:
    A proposito, usando @c{or}, la escena con el acomodador se escribiria así:

#     ..src > elisp
#       (or (holding-on-to-guest) (find-and-take-arm-of-guest))
#     < src..
    ..src > elisp
      (or (tomar-al-invitado) (encontrar-y-tomar-del-brazo-al-invitado))
    < src..

# *** The @c{let} Expression in @c{insert-buffer}
*** La expresión @c{let} en @c{insert-buffer}

#     After ensuring that the variable @c{buffer} refers to a buffer itself and
#     not just to the name of a buffer, the @c{insert-buffer function}
#     continues with a @c{let} expression. This specifies three local
#     variables, @c{start}, @c{end}, and @c{newmark} and binds them to the
#     initial value @c{nil}. These variables are used inside the remainder of
#     the @c{let} and temporarily hide any other occurrence of variables of the
#     same name in Emacs until the end of the @c{let}.
    Después de asegurarse que la variable @c{buffer} se refiere a un buffer en
    sí y no solo al nombre de uno, la función @c{insert-buffer} continúa
    con una expresión @c{let}. Esta especifica tres variables locales,
    @c{start}, @c{end} y @c{newmark} y las une al valor inicial @c{nil}. Estas
    variables se utilizan dentro del resto de @c{let} y ocultan temporalmente
    cualquier otra ocurrencia de variables con el mismo nombre en Emacs hasta el
    final de @c{let}.

#     The body of the @c{let} contains two @c{save-excursion} expressions.
#     First, we will look at the inner @c{save-excursion} expression in detail.
#     The expression looks like this:
    El cuerpo de @c{let} contiene dos expresiones @c{save-excursion}. Primero,
    veremos la expresión interna @c{save-excursion} en detalle. La expresión
    se ve asi:

#     ..src > elisp
#       (save-excursion
#         (set-buffer buffer)
#         (setq start (point-min) end (point-max)))
#     < src..
    ..src > elisp
      (save-excursion
        (set-buffer buffer)
        (setq start (point-min) end (point-max)))
    < src..

#     The expression @c{(set-buffer buffer)} changes Emacs's attention from the
#     current buffer to the one from which the text will copied. In that
#     buffer, the variables @c{start} and @c{end} are set to the beginning and
#     end of the buffer, using the commands @c{point-min} and @c{point-max}.
#     Note that we have here an illustration of how @c{setq} is able to set two
#     variables in the same expression. The first argument of @c{setq} is set
#     to the value of its second, and its third argument is set to the value of
#     its fourth.
    La expresión @c{(set-buffer buffer)} cambia la atención de Emacs del
    búfer actual al buffer desde donde se copiara el texto. En ese búfer las
    variables @c{start} y @c{end} se asignan al inicio y al fin del búfer,
    usando los comandos @c{point-min} y @c{point-max}. Observa que
    tenemos aquí un ejemplo de cómo @c{setq} es capaz de asignar dos variables
    en la misma expresión. El primer argumento de @c{setq} se establece al valor
    del segundo, y el tercer argumento se establece al valor del cuarto.

#     After the body of the inner @c{save-excursion} is evaluated, the
#     @c{save-excursion} restores the original buffer, but @c{start} and
#     @c{end} remain set to the values of the beginning and end of the buffer
#     from which the text will be copied.
    Después de evaluar el interior del cuerpo de @c{save-excursion},
    @c{save-excursion} restaura el búfer original, pero @c{start} y @c{end}
    retienen los valores del inicio y fin del búfer del que se copiara el texto.

#     The outer @c{save-excursion} expression looks like this:
    La expresión extena de @c{save-excursion} luce asi:

#     ..src > elisp
#       (save-excursion
#         (inner-save-excursion-expression
#            (go-to-new-buffer-and-set-start-and-end)
#         (insert-buffer-substring buffer start end)
#         (setq newmark (point)))
#     < src..
    ..src > elisp
      (save-excursion
        (expresion-interior-de-save-excursion
           (ir-al-nuevo-bufer-y-establecer-start-y-end)
        (insert-buffer-substring buffer start end)
        (setq newmark (point)))
    < src..

#     The @c{insert-buffer-substring} function copies the text @e{into} the
#     current buffer @e{from} the region indicated by @c{start} and @c{end} in
#     @c{buffer}. Since the whole of the second buffer lies between @c{start}
#     and @c{end}, the whole of the second buffer is copied into the buffer you
#     are editing. Next, the value of point, which will be at the end of the
#     inserted text, is recorded in the variable @c{newmark}.
    La función @c{insert-buffer-substring} copia el texto @e{dento} del búfer
    actual @e{desde} la región indicada por @c{start} y @c{end} en el
    @c{buffer}. Puesto que la totalidad del segundo búfer se encuentra entre
    @c{start} y @c{end}, todo dentro del segundo búfer se copia el bufer que
    se esta editando. A continuacion, el valor del punto, que estara al final del
    texto insertado, se registra en la variable @c{newmark}.

#     After the body of the outer @c{save-excursion} is evaluated, point and
#     mark are relocated to their original places.
    Después de evaluar el cuerpo del @c{save-excursion} externo, el punto y la
    marca se vuelven a colocar en su posicion original.

#     However, it is convenient to locate a mark at the end of the newly
#     inserted text and locate point at its beginning. The @c{newmark}
#     variable records the end of the inserted text. In the last line of the
#     @c{let} expression, the @c{(push-mark newmark)} expression function sets
#     a mark to this location.  (The previous location of the mark is still
#     accessible; it is recorded on the mark ring and you can go back to it
#     with @k{C-u C-@k{SPC}}.)  Meanwhile, point is located at the beginning of
#     the inserted text, which is where it was before you called the insert
#     function, the position of which was saved by the first
#     @c{save-excursion}.
    Sin embargo, es conveniente ubicar una marca al fin del texto recien
    insertado y ubicar el punto al principio. La variable @c{newmark} registra
    el fin del texto insertado. En la última línea de la expresión @c{let}, la
    expresión @c{(push-mark newmark)} asigna una marca a esta posición. (La
    posición anterior de la marca aun es accesible; se registra en el anillo de
    marcas y puedes volver a ella con @k{C-u C-SPC}.) Mientras tanto, el punto
    se encuentra al principio del texto insertado, que es donde estaba antes de
    llamar a la función de insercion, cuya posición fue guardada por la primer
    @c{save-excursion}.

#     The whole @c{let} expression looks like this:
    La expresión @c{let} completa se ve asi:

#     ..src > elisp
#       (let (start end newmark)
#         (save-excursion
#           (save-excursion
#             (set-buffer buffer)
#             (setq start (point-min) end (point-max)))
#           (insert-buffer-substring buffer start end)
#           (setq newmark (point)))
#         (push-mark newmark))
#     < src..
    ..src > elisp
      (let (start end newmark)
        (save-excursion
          (save-excursion
            (set-buffer buffer)
            (setq start (point-min) end (point-max)))
          (insert-buffer-substring buffer start end)
          (setq newmark (point)))
        (push-mark newmark))
    < src..

#     Like the @c{append-to-buffer} function, the @c{insert-buffer} function
#     uses @c{let}, @c{save-excursion}, and @c{set-buffer}. In addition, the
#     function illustrates one way to use @c{or}. All these functions are
#     building blocks that we will find and use again and again.
    Al igual que la función @c{append-to-buffer}, la función @c{insert-buffer}
    utiliza @c{let}, @c{save-excursion} y @c{set-buffer}. Además, la función
    ilustra una forma de utilizar @c{or}. Todas estas funciones son bloques de
    construccion que vamos a encontrar y utilizar una y otra vez.

# *** New Body for @c{insert-buffer}
*** Nuevo cuerpo para @c{insert-buffer}

#     The body in the GNU Emacs 22 version is more confusing than the original.
    El cuerpo en la versión 22 de GNU Emacs es más confuso que el original.

#     It consists of two expressions,
    Se compone de dos expresiones

#     ..src > elisp
#       (push-mark
#        (save-excursion
#          (insert-buffer-substring (get-buffer buffer))
#          (point)))
#
#       nil
#     < src..
    ..src > elisp
      (push-mark
       (save-excursion
         (insert-buffer-substring (get-buffer buffer))
         (point)))

      nil
    < src..

#     except, and this is what confuses novices, very important work is done
#     inside the @c{push-mark} expression.
    excepto que, y esto es lo que confunde a los novatos, se hace un
    trabajo muy importante al interior de la expresión @c{push-mark}.

#     The @c{get-buffer} function returns a buffer with the name provided. You
#     will note that the function is @e{not} called @c{get-buffer-create}; it
#     does not create a buffer if one does not already exist. The buffer
#     returned by @c{get-buffer}, an existing buffer, is passed to
#     @c{insert-buffer-substring}, which inserts the whole of the buffer (since
#     you did not specify anything else).
    La función @c{get-buffer} devuelve un búfer con el nombre proporcionado.
    Notaras que la función @e{no} se llama @c{get-buffer-create}; no crea
    un búfer si no existe ya. El búfer devuelto por @c{get-buffer}, un
    búfer existente, se pasa a @c{insert-buffer-substring}, que inserta todo el
    búfer (ya que no se especifica ninguna cosa más).

#     The location into which the buffer is inserted is recorded by
#     @c{push-mark}. Then the function returns @c{nil}, the value of its last
#     command. Put another way, the @c{insert-buffer} function exists only to
#     produce a side effect, inserting another buffer, not to return any value.
    La posición en la que se inserta el buffer se registra por @c{push-mark}.
    Despues la función devuelve @c{nil}, el valor de su último comando. Dicho de
    otra manera, la función @c{insert-buffer} existe solo para producir un
    efecto secundario, insertando otro buffer, no para devolver ningun valor.

# ** Complete Definition of @c{beginning-of-buffer}
** Definición completa de @c{beginning-of-buffer}

#    The basic structure of the @c{beginning-of-buffer} function has already
#    been discussed. (See Section @l{#A Simplified @c{beginning-of-buffer}
#    Definition}.) This section describes the complex part of the definition.
   Ya se ha discutido la estructura básica de la función @c{beginning-of-buffer}.
   (Consulta la Seccion @l{#Una definición simplificada de @c{beginning-of-buffer}}).
   Esta sección describe la parte compleja de la definición.

#    As previously described, when invoked without an argument,
#    @c{beginning-of-buffer} moves the cursor to the beginning of the buffer
#    (in truth, the beginning of the accessible portion of the buffer), leaving
#    the mark at the previous position. However, when the command is invoked
#    with a number between one and ten, the function considers that number to
#    be a fraction of the length of the buffer, measured in tenths, and Emacs
#    moves the cursor that fraction of the way from the beginning of the
#    buffer. Thus, you can either call this function with the key command
#    @k{M-<}, which will move the cursor to the beginning of the buffer, or
#    with a key command such as @k{C-u 7 M-<} which will move the cursor to a
#    point 70% of the way through the buffer. If a number bigger than ten is
#    used for the argument, it moves to the end of the buffer.
   Como se ha descrito anteriormente, cuando se invoca a @c{beginning-of-buffer}
   sin argumento, mueve el cursor al inicio del búfer (en realidad, al inicio
   de la porción accesible del búfer), dejando la marca en la posición
   anterior. Sin embargo, cuando el comando se invoca con un número entre uno y
   diez, la función considera que ese número es una fracción del tamaño del búfer,
   medido en decimas, y Emacs mueve el cursor a dicha fracción del reccorrido
   desde el inicio del búfer. Por lo tanto, puedes llamar a esta función con el
   comando de teclado @k{M-<}, que moverá el cursor al principio del búfer, o
   con un comando de teclado como @k{C-u 7 M-<} que moverá el cursor a un 70%
   del recorrido a través del búfer. Si se utiliza un número mayor a diez como
   argumento, se movera al final del búfer.

#    The @c{beginning-of-buffer} function can be called with or without an
#    argument. The use of the argument is optional.
   La función @c{beginning-of-buffer} puede llamarse con o sin argumentos. El
   uso del argumento es opcional.

# *** Optional Arguments
*** Argumentos opcionales

#     Unless told otherwise, Lisp expects that a function with an argument in
#     its function definition will be called with a value for that argument.
#     If that does not happen, you get an error and a message that says
#     @'{Wrong number of arguments}.
    A menos que se diga lo contrario, Lisp espera que una función con un
    argumento en su definición de función se llamada con un valor para ese
    argumento. Si esto no ocurre, se obtiene un error y un mensaje que dice
    @'{Wrong number of arguments} @%i"(Número de argumentos erróneo).

#     However, optional arguments are a feature of Lisp: a particular
#     @:{keyword} is used to tell the Lisp interpreter that an argument is
#     optional. The keyword is @c{&optional}.  (The @'c{&} in front of
#     @'c{optional} is part of the keyword.)  In a function definition, if an
#     argument follows the keyword @c{&optional}, no value need be passed to
#     that argument when the function is called.
    Sin embargo, los argumentos opcionales son una caracteristica de Lisp: se
    utiliza una @:{palabra clave} particular para decirle al intérprete Lisp
    que un argumento es opcional. La palabra clave es @c{&optional}. (El @'c{&}
    al frente de @'c{optional} es parte de la palabra clave.) En una definición
    de función, si un argumento va despues de la palabra clave @c{&optional}, no
    es necesario pasar ningún valor a ese argumento al llamar a la función.

#     The first line of the function definition of @c{beginning-of-buffer}
#     therefore looks like this:
    Por lo tanto la primera línea de la definición de función de
    @c{beginning-of-buffer} tiene este aspecto:

#     ..src > elisp
#       (defun beginning-of-buffer (&optional arg)
#     < src..
    ..src > elisp
      (defun beginning-of-buffer (&optional arg)
    < src..

#     In outline, the whole function looks like this:
    En lineas generales, toda la función luce asi:

#     ..src > elisp
#       (defun beginning-of-buffer (&optional arg)
#         "documentation…"
#         (interactive "P")
#         (or (is-the-argument-a-cons-cell arg)
#             (and are-both-transient-mark-mode-and-mark-active-true)
#             (push-mark))
#         (let (determine-size-and-set-it)
#         (goto-char
#           (if-there-is-an-argument
#               figure-out-where-to-go
#             else-go-to
#             (point-min))))
#          do-nicety
#     < src..
    ..src > elisp
      (defun beginning-of-buffer (&optional arg)
        "documentacion…"
        (interactive "P")
        (or (es-el-argumento-una-cons-cell argumento)
            (and ambos-transient-mark-mode-y-mark-active-son-verdadero)
            (push-mark))
        (let (determina-el-tamano-y-lo-establece)
        (goto-char
          (si-hay-un-argumento
              averigua-donde-ir
            de-otro-modo-va-a
            (point-min))))
         do-nicety
    < src..

#     The function is similar to the @c{simplified-beginning-of-buffer}
#     function except that the @c{interactive} expression has @c{"P"} as an
#     argument and the @c{goto-char} function is followed by an if-then-else
#     expression that figures out where to put the cursor if there is an
#     argument that is not a cons cell.
    La función es similar a la función @c{beginning-of-buffer-simplificado}
    excepto que la expresión @c{interactive} tiene @c{"P"} como argumento y la
    función @c{goto-char} es seguida por una expresión if-then-else que
    calcula donde poner el cursor si hay un argumento que no es un cons cell.

#     (Since I do not explain a cons cell for many more chapters, please
#     consider ignoring the function @c{consp}. See Section @l{#How Lists are
#     Implemented}, and Section @l{elisp.html#Cons Cell Type<>Cons Cell and List
#     Types} in @e{The GNU Emacs Lisp Reference Manual}.)
    (Puesto que no explico que es un @e(cons cell) en muchos capítulos, por
    favor, considera ignorar la función @c{consp}. Consulta la Seccion @l{#Cómo se
    implementan las listas}, y la Seccion @"l{elisp.html#Cons Cell Type<>Cons
    Cell y Tipos de Listas} en @e(El Manual de Referencia GNU Emacs Lisp)).

#     The @c{"P"} in the @c{interactive} expression tells Emacs to pass a
#     prefix argument, if there is one, to the function in raw form. A prefix
#     argument is made by typing the @k{META} key followed by a number, or by
#     typing @k{C-u} and then a number.  (If you don't type a number, @k{C-u}
#     defaults to a cons cell with a 4. A lowercase @c{"p"} in the
#     @c{interactive} expression causes the function to convert a prefix arg to
#     a number.)
    La @c{"P"} en la expresión @c{interactive} le indica a Emacs que pase un
    argumento prefijo, si lo hay, en su forma @"(plana) sin procesar. Un
    argumento prefijo se crea presionando la tecla @k{META} seguida por un
    número, o pulsando @k{C-u} y luego un número. (Si no escribes un número,
    @k{C-u} por defecto pasa un cons cell con un 4. Una @c{"p"} minúscula en la
    expresión @c{interactive} hace que la función convierta un argumento prefijo
    a un número.)

#     The true-or-false-test of the @c{if} expression looks complex, but it is
#     not: it checks whether @c{arg} has a value that is not @c{nil} and
#     whether it is a cons cell.  (That is what @c{consp} does; it checks
#     whether its argument is a cons cell.)  If @c{arg} has a value that is not
#     @c{nil} (and is not a cons cell), which will be the case if
#     @c{beginning-of-buffer} is called with a numeric argument, then this
#     true-or-false-test will return true and the then-part of the @c{if}
#     expression will be evaluated. On the other hand, if
#     @c{beginning-of-buffer} is not called with an argument, the value of
#     @c{arg} will be @c{nil} and the else-part of the @c{if} expression will
#     be evaluated. The else-part is simply @c{point-min}, and when this is
#     the outcome, the whole @c{goto-char} expression is @c{(goto-char
#     (point-min))}, which is how we saw the @c{beginning-of-buffer} function
#     in its simplified form.
    La prueba verdadero-o-falso de la expresión @c{if} parece compleja, pero no
    lo es: comprueba si @c{arg} tiene un valor que no es @c{nil} y si
    es un cons cell. (Esto es lo que hace @c{consp}; comprueba si su argumento
    es un cons cell.) Si @c{arg} tiene un valor distinto a @c{nil} (y no
    es un cons cell), que será el caso si @c{beginning-of-buffer} se llama con
    un argumento numerico, la prueba verdadero-o-falso devolverá verdadero y se
    evaluara la parte-then de la expresión @c{if}. Por otro lado, si
    @c{beginning-of-bufer} no se llama con un argumento, el valor de
    @c{arg} será @c{nil} y se evaluara la parte-else de la expresión
    @c{if}. La parte-else es simplemente @c{point-min}, y cuando este es el
    resultado, toda la expresión @c{goto-char} es @c{(goto-char (point-min))},
    que es cómo vimos la función @c{beginning-of-buffer} en su forma
    simplificada.

# *** @c{beginning-of-buffer} with an Argument
*** @c{beginning-of-buffer} con un argumento

#     When @c{beginning-of-buffer} is called with an argument, an expression is
#     evaluated which calculates what value to pass to @c{goto-char}. This
#     expression is rather complicated at first sight. It includes an inner
#     @c{if} expression and much arithmetic. It looks like this:
    Cuando se llama a @c{beginning-of-buffer} con un argumento, se evalua una
    expresión que calcula que valor pasar a @c{goto-char}. A primera vista esta
    expresion es bastante compleja. Incluye una expresión @c{if} y mucha
    aritmética. Se ve así:

#     ..src > elisp
#       (if (> (buffer-size) 10000)
#           ;; Avoid overflow for large buffer sizes!
#           (* (prefix-numeric-value arg)
#              (/ size 10))
#         (/ (+ 10
#               (* size (prefix-numeric-value arg)))
#            10))
#     < src..
    ..src > elisp
      (if (> (buffer-size) 10000)
          ;; Evita el desbordamiento en buffers de gran tamaño!
          (* (prefix-numeric-value arg)
             (/ size 10))
        (/ (+ 10
              (* size (prefix-numeric-value arg)))
           10))
    < src..

#     Like other complex-looking expressions, the conditional expression within
#     @c{beginning-of-buffer} can be disentangled by looking at it as parts of
#     a template, in this case, the template for an if-then-else expression.
#     In skeletal form, the expression looks like this:
    Como otras expresiones que parecen complejas, la expresión condicional
    dentro de @c{beginning-of-buffer} se puede desenredar viendola como partes
    de una plantilla, en este caso, con la plantilla para una expresión
    if-then-else. En forma esquelética, la expresión se ve así:

#     ..src > elisp
#       (if (buffer-is-large
#           divide-buffer-size-by-10-and-multiply-by-arg
#         else-use-alternate-calculation
#     < src..
    ..src > elisp
      (if (buffer-es-grande
          divide-el-tamaño-del-buffer-por-10-y-multiplicalo-por-arg
        de-otra-forma-utiliza-el-calculo-alternativo
    < src..

#     The true-or-false-test of this inner @c{if} expression checks the size of
#     the buffer. The reason for this is that the old version 18 Emacs used
#     numbers that are no bigger than eight million or so and in the
#     computation that followed, the programmer feared that Emacs might try to
#     use over-large numbers if the buffer were large. The term ‘overflow’,
#     mentioned in the comment, means numbers that are over large. More recent
#     versions of Emacs use larger numbers, but this code has not been touched,
#     if only because people now look at buffers that are far, far larger than
#     ever before.
    La prueba verdadero-o-falso de la expresión @c{if} interna comprueba el
    tamaño del buffer. La razón de esto es que la vieja versión de Emacs 18
    utilizaba números que no superaban los ocho millones y en el siguiente
    calculo, el programador temía que Emacs pudiera intentar usar numeros
    demasiado grandes si el búfer era extenso. El término ‘desbordamiento’,
    que se menciona en el comentario, significa que los números son demaciado
    grandes. Las versiones más recientes de Emacs utilizan números mas grandes,
    pero este código no ha sido tocado, aunque solo sea porque la gente ahora
    mira búfers que son mucho, mucho mas grandes que antes.

#     There are two cases: if the buffer is large and if it is not.
    Hay dos casos: si el búfer es grande, o si no lo es.

# **** What happens in a large buffer
**** Qué ocurre en un búfer de gran tamaño

#      In @c{beginning-of-buffer}, the inner @c{if} expression tests whether
#      the size of the buffer is greater than 10,000 characters. To do this,
#      it uses the @c{>} function and the computation of @c{size} that comes
#      from the @c(let) expression.
     En @c{beginning-of-buffer}, la expresión @c{if} interna prueba si el tamaño
     del búfer es mayor a 10000 caracteres. Para ello, se utiliza la
     función @c{>} y el calculo de @c{size} que proviene de la expresión @c(let).

#      In the old days, the function @c{buffer-size} was used. Not only was
#      that function called several times, it gave the size of the whole
#      buffer, not the accessible part. The computation makes much more sense
#      when it handles just the accessible part.  (See Section @l{#Narrowing and
#      Widening}, for more information on focusing attention to an ‘accessible’
#      part.)
     En los viejos tiempos, se utilizaba la función @c{buffer-size}. No solo se
     llamo varias ocaciones esa funcion, sino que dio el tamaño de todo el
     búfer, no la parte accesible. El calculo tiene mucho más sentido cuando se
     maneja solo la parte accesible. (Consulta la Seccion @l{#Reducir y Extender},
     para obtener más información sobre como centrar la atención en una parte
     ‘accesible’.)

#      The line looks like this:
     La linea se ve asi:

#      ..src > elisp
#        (if (> size 10000)
#      < src..
     ..src > elisp
       (if (> size 10000)
     < src..

#      When the buffer is large, the then-part of the @c{if} expression is
#      evaluated. It reads like this (after formatting for easy reading):
     Cuando el búfer es grande, se evalua la parte-then de la expresión
     @c{if}. Se lee así (después de formatearlo para facilitar la lectura):

#      ..src > elisp
#        (*
#          (prefix-numeric-value arg)
#          (/ size 10))
#      < src..
     ..src > elisp
       (*
         (prefix-numeric-value arg)
         (/ size 10))
     < src..

#      This expression is a multiplication, with two arguments to the function
#      @c{*}.
     Esta expresión es una multiplicación, con dos argumentos para la función
     @c{*}.

#      The first argument is @c{(prefix-numeric-value arg)}. When @c{"P"} is
#      used as the argument for @c{interactive}, the value passed to the
#      function as its argument is passed a “raw prefix argument”, and not a
#      number.  (It is a number in a list.)  To perform the arithmetic, a
#      conversion is necessary, and @c{prefix-numeric-value} does the job.
     El primer argumento es @c{(prefix-numeric-value arg)}. Cuando se usa
     @c{"P"} como argumento para @c{interactive}, el valor pasado a la función
     como argumento es un “argumento prefijo en bruto”, y no un número. (Es un
     número en una lista). Para realizar el calculo, se necesita una conversión,
     y @c{prefix-numeric-value} hace el trabajo.

#      The second argument is @c{(/ size 10)}. This expression divides the
#      numeric value by ten––the numeric value of the size of the accessible
#      portion of the buffer. This produces a number that tells how many
#      characters make up one tenth of the buffer size.  (In Lisp, @c{/} is
#      used for division, just as @c{*} is used for multiplication.)
     El segundo argumento es @c{(/ size 10)}. Esta expresión divide el valor
     numérico por diez––el valor numérico del tamaño de la porción accesible del
     búfer. Esto produce un número que indica cuántos caracteres componen
     una decima parte del tamaño del búfer. (En Lisp, @c{/} se utiliza para la
     división, igual que @c{*} se utiliza para la multiplicación.)

#      In the multiplication expression as a whole, this amount is multiplied
#      by the value of the prefix argument––the multiplication looks like this:
     En la expresión de multiplicación como un todo, esta cantidad se
     multiplica por el valor del argumento prefijo––la multiplicación es la
     siguiente:

#      ..src > elisp
#        (* numeric-value-of-prefix-arg
#           number-of-characters-in-one-tenth-of-the-accessible-buffer)
#      < src..
     ..src > elisp
       (* valor-numerico-del-argumento-prefijo-arg
          numero-de-caracteres-en-una-decima-parte-de-la-porcion-accesible-del-buffer)
     < src..

#      If, for example, the prefix argument is @'{7}, the one-tenth value will
#      be multiplied by 7 to give a position 70% of the way through.
     Si, por ejemplo, el argumento prefijo es @'{7}, el valor de una decima parte
     será multiplicado por 7 para dar una posición del 70% del trayecto.

#      The result of all this is that if the accessible portion of the buffer
#      is large, the @c{goto-char} expression reads like this:
     El resultado de todo esto es que si la porción accesible del búfer es
     grande, la expresión @c{goto-char} es la siguiente:

#      ..src > elisp
#        (goto-char (* (prefix-numeric-value arg)
#                      (/ size 10)))
#      < src..
     ..src > elisp
       (goto-char (* (prefix-numeric-value arg)
                     (/ size 10)))
     < src..

#      This puts the cursor where we want it.
     Esto coloca el cursor donde lo queremos.

# **** What happens in a small buffer
**** Lo que sucede en un búfer pequeño

#      If the buffer contains fewer than 10,000 characters, a slightly
#      different computation is performed. You might think this is not
#      necessary, since the first computation could do the job. However, in a
#      small buffer, the first method may not put the cursor on exactly the
#      desired line; the second method does a better job.
     Si el búfer contiene menos de 10,000 caracteres, se lleva a cabo un calculo
     ligeramente diferente. Podrías pensar que esto no es necesario, ya que el
     primer calculo podría hacer el trabajo. Sin embargo, en un búfer pequeño,
     el primer método puede no colocar el cursor exactamente en la línea
     deseada; el segundo método hace un mejor trabajo.

#      The code looks like this:
     El código es el siguiente:

#      ..src > elisp
#        (/ (+ 10 (* size (prefix-numeric-value arg))) 10))
#      < src..
     ..src > elisp
       (/ (+ 10 (* size (prefix-numeric-value arg))) 10))
     < src..

#      This is code in which you figure out what happens by discovering how the
#      functions are embedded in parentheses. It is easier to read if you
#      reformat it with each expression indented more deeply than its enclosing
#      expression:
     Para averiguar que ocure en este código debemos descubrir como se anidan
     las funciones entre paréntesis. Es mas fácil de leer si se reformatea cada
     expresión, indentando la expresión que contiene:

#      ..src > elisp
#          (/
#           (+ 10
#              (*
#               size
#               (prefix-numeric-value arg)))
#           10))
#      < src..
     ..src > elisp
         (/
          (+ 10
             (*
              size
              (prefix-numeric-value arg)))
          10))
     < src..

#      Looking at parentheses, we see that the innermost operation is
#      @c{(prefix-numeric-value arg)}, which converts the raw argument to a
#      number. In the following expression, this number is multiplied by the
#      size of the accessible portion of the buffer:
     Observando los paréntesis, vemos que la operación mas profunda es
     @c{(prefix-numeric-value arg)}, que convierte el argumento prefijo en bruto
     a un número. En la siguiente expresión, este número se multiplica por el
     tamaño de la porción accesible del búfer:

#      ..src > elisp
#        (* size (prefix-numeric-value arg))
#      < src..
     ..src > elisp
       (* size (prefix-numeric-value arg))
     < src..

#      This multiplication creates a number that may be larger than the size of
#      the buffer––seven times larger if the argument is 7, for example. Ten
#      is then added to this number and finally the large number is divided by
#      ten to provide a value that is one character larger than the percentage
#      position in the buffer.
     Esta multiplicación crea un número que puede ser mayor al tamaño del
     buffer––siete veces mayor si el argumento es 7, por ejemplo. Luego se suma
     diez a éste numero y finalmente el número se divide por 10 para
     proporcionar un valor que es un carácter más grande que la posición
     porcentual en el búfer.

#      The number that results from all this is passed to @c{goto-char} and the
#      cursor is moved to that point.
     El número que resulta de todo esto se pasa a @c{goto-char} y el cursor
     se mueve a ese punto.

# *** The Complete @c{beginning-of-buffer}
*** Funcion @c{beginning-of-buffer} Completa

#     Here is the complete text of the @c{beginning-of-buffer} function:
    Aquí está el texto completo de la función @c{beginning-of-buffer}:

#     ..src > elisp
    ..src > elisp
#       (defun beginning-of-buffer (&optional arg)
      (defun beginning-of-buffer (&optional arg)
#         "Move point to the beginning of the buffer;
#       leave mark at previous position.
#       With \\[universal-argument] prefix,
#       do not set mark at previous position.
#       With numeric arg N,
#       put point N/10 of the way from the beginning.
        "Mueve el punto al principio del bufer;
      deja la marca en la posicion anterior.
      Con el prefijo \\[universal-argument],
      no establece la marca en la posicion anterior.
      Con un argumento numerico N,
      coloca el punto N/10 del camino desde el inicio.

#       If the buffer is narrowed,
#       this command uses the beginning and size
#       of the accessible part of the buffer.
      Si el bufer tiene activo narrowing,
      este comando utiliza el principio y el tamaño
      de la parte accesible del bufer.

#       Don't use this command in Lisp programs!
#       \(goto-char (point-min)) is faster
#       and avoids clobbering the mark."
      No utilice este comando en programas Lisp!
      \(goto-char (point-min)) es mas rapido y evita
      tocar la marca."
#         (interactive "P")
        (interactive "P")
#         (or (consp arg)
#             (and transient-mark-mode mark-active)
#             (push-mark))
        (or (consp arg)
            (and transient-mark-mode mark-active)
            (push-mark))
#         (let ((size (- (point-max) (point-min))))
#           (goto-char (if (and arg (not (consp arg)))
#                          (+ (point-min)
#                             (if (> size 10000)
#                                 ;; Avoid overflow for large buffer sizes!
#                                 (* (prefix-numeric-value arg)
#                                    (/ size 10))
#                               (/ (+ 10 (* size (prefix-numeric-value arg)))
#                                  10)))
#                        (point-min))))
#         (if arg (forward-line 1)))
        (let ((size (- (point-max) (point-min))))
          (goto-char (if (and arg (not (consp arg)))
                         (+ (point-min)
                            (if (> size 10000)
                                ;; Evita el desbordamiento en los búfers de gran tamaño!
                                (* (prefix-numeric-value arg)
                                   (/ size 10))
                              (/ (+ 10 (* size (prefix-numeric-value arg)))
                                 10)))
                       (point-min))))
        (if arg (forward-line 1)))
#     < src..
    < src..

#     Except for two small points, the previous discussion shows how this
#     function works. The first point deals with a detail in the documentation
#     string, and the second point concerns the last line of the function.
    Excepto por dos pequeños puntos, la discusión anterior muestra cómo funciona
    esta función. El primer punto se refiere a un detalle en la cadena de
    documentación, y el segundo se refiere a la última línea de la función.

#     In the documentation string, there is reference to an expression:
    En la cadena de documentación, hay una referencia a una expresión:

#     ..example >
#       \\[universal-argument]
#     < example..
    ..example >
      \\[universal-argument]
    < example..

#     A @'{\\} is used before the first square bracket of this expression.  This
#     @'{\\} tells the Lisp interpreter to substitute whatever key is currently
#     bound to the @'{[…]}. In the case of @c{universal-argument}, that is
#     usually @k{C-u}, but it might be different.  (See Section
#     @l{elisp.html#Documentation Tips<>Documentation Tips} in @e{The GNU Emacs Lisp Reference
#     Manual}, for more information.)
    Se usa Un @'{\\} antes del primer corchete de esta expresión. Este @'{\\} le
    indica al intérprete Lisp que sustituya cualquier clave qué se encuentre
    dentro de @'{[…]} por su convinacion de teclado actual. En el caso de
    @c{universal-argument}, suele ser @k{C-u}, pero podría ser distinta. (Consulta la
    Sección @l{elisp.html#Documentation Tips<>Consejos para Cadenas de
    Documentación} en @e(El Manual de Referencia de GNU Emacs Lisp), para más
    información.)

#     Finally, the last line of the @c{beginning-of-buffer} command says to
#     move point to the beginning of the next line if the command is invoked
#     with an argument:
    Finalmente, la última línea del comando @c{beginning-of-buffer} dice que hay
    que mover el punto al inicio de la siguiente línea si el comando se invoca
    con un argumento:

#     ..src > elisp
#       (if arg (forward-line 1)))
#     < src..
    ..src > elisp
      (if arg (forward-line 1)))
    < src..

#     This puts the cursor at the beginning of the first line after the
#     appropriate tenths position in the buffer. This is a flourish that means
#     that the cursor is always located @e{at least} the requested tenths of
#     the way through the buffer, which is a nicety that is, perhaps, not
#     necessary, but which, if it did not occur, would be sure to draw
#     complaints.
    Esto coloca el cursor al inicio de la primer línea despues de la posicion
    inidicada en decimas en el búfer. Esto significa que el cursor siempre se
    localiza @e{al menos} las decimas del recorrido solicitadas del búfer, esta
    es una sutiliza, quizás, no necesaria, pero que, si no ocurriera, seguro
    suscitaria quejas.

#     On the other hand, it also means that if you specify the command with a
#     @k{C-u}, but without a number, that is to say, if the ‘raw prefix
#     argument’ is simply a cons cell, then the command puts you at the
#     beginning of the second line … I don't know whether this is
#     intended or whether no one has dealt with the code to avoid this
#     happening.
    Por otro lado, tambien significa que si se especifica el comando con @k{C-u},
    pero sin un número, es decir, si el ‘argumento prefijo en bruto’ simplemente
    es un cons cell, entonces el comando te coloca al inicio de la segunda línea
    … no sé si se pretende esto o si nadie ha tratado el código para evitar que
    esto suceda.

# ** A Few More Complex Functions Review <> Review
** Repaso: Algunas Funciones Más Complejas <> Repaso

#    Here is a brief summary of some of the topics covered in this chapter.
   He aquí un breve resumen de algunos de los temas cubiertos en este capítulo.

#    - @c(or) ::
   - @c(or) ::

#      Evaluate each argument in sequence, and return the value of the first
#      argument that is not @c{nil}; if none return a value that is not
#      @c{nil}, return @c{nil}. In brief, return the first true value of the
#      arguments; return a true value if one @e{or} any of the others are true.
     Evalúa cada argumento en secuencia, y devuelve el valor del primer
     argumento que no es @c{nil}, si ninguno devuelve un valor que no sea
     @c{nil}, devuelve @c{nil}. En resumen, devuelve el primer valor verdadero
     de los argumento; devuelve un valor verdadero si uno @e{o} cualquiera de
     los otros es verdadero.

#    - @c(and) ::
   - @c(and) ::

#      Evaluate each argument in sequence, and if any are @c{nil}, return
#      @c{nil}; if none are @c{nil}, return the value of the last argument. In
#      brief, return a true value only if all the arguments are true; return a
#      true value if one @e{and} each of the others is true.
     Evalúa cada argumento en secuencia, y si alguno es @c{nil}, devuelve
     @c{nil}; si ninguno es @c{nil}, devuelve el valor del último argumento. En
     resumen, devuelve un valor verdadero solo si todos los argumentos son
     verdaderos; devuelve un valor verdadero si uno @e{y} cada uno de los otros
     son verdadero.

#    - @c(&optional) ::
   - @c(&optional) ::

#      A keyword used to indicate that an argument to a function definition is
#      optional; this means that the function can be evaluated without the
#      argument, if desired.
     Una palabra clave utilizada para indicar que un argumento en una definición
     de función es opcional; esto significa que la función se puede evaluar sin
     el argumento, si se desea.

#    - @c(prefix-numeric-value) ::
   - @c(prefix-numeric-value) ::

#      Convert the ‘raw prefix argument’ produced by @c{(interactive "P")} to a
#      numeric value.
     Convierte el ‘argumento prefijo en bruto’ producido por @c{(interactive
     "P")} en un valor numérico.

#    - @c(forward-line) ::
   - @c(forward-line) ::

#      Move point forward to the beginning of the next line, or if the argument
#      is greater than one, forward that many lines. If it can't move as far
#      forward as it is supposed to, @c{forward-line} goes forward as far as it
#      can and then returns a count of the number of additional lines it was
#      supposed to move but couldn't.
     Mueve el punto hacia adelante al principio de la siguiente línea, o si el
     argumento es mayor a uno, hacia delante varias líneas. Si no puede avanzar
     tanto hacia delante como se supone, @c{forward-line} va hacia adelante
     tan lejos como pueda y luego devuelve un conteo del número de líneas
     adicionales que debia avanzar poro no pudo.

#    - @c(erase-buffer) ::
   - @c(erase-buffer) ::

#      Delete the entire contents of the current buffer.
     Elimina todo el contenido del búfer actual.

#    - @c(bufferp) ::
   - @c(bufferp) ::

#      Return @c{t} if its argument is a buffer; otherwise return @c{nil}.
     Devuelve @c{t} si su argumento es un búfer; de otro modo devuelve
     @c{nil}.

# ** @c{optional} Argument Exercise
** Ejercicio con el argumento @c{opcional}

#    Write an interactive function with an optional argument that tests whether
#    its argument, a number, is greater than or equal to, or else, less than
#    the value of @c{fill-column}, and tells you which, in a message. However,
#    if you do not pass an argument to the function, use 56 as a default value.
   Escribe una función interactiva con un argumento opcional que comprueve si su
   argumento, un número, es mayor o igual o menor que el valor de
   @c{fill-column}, y lo informe, en un mensaje. Sin embargo, si no se pasa un
   argumento a la función, utiliza 56 como valor por defecto.

# * Narrowing and Widening
* Reducir y Extender

#   Narrowing is a feature of Emacs that makes it possible for you to focus
#   on a specific part of a buffer, and work without accidentally changing
#   other parts. Narrowing is normally disabled since it can confuse
#   novices.
  La reduccion @%i(narrowing) es una funcionalidad de Emacs que hace posible que
  puedas focalizarte en una parte específica de un búfer, y trabajar sin cambiar
  accidentalmente otras partes. La reduccion normalmente se deshabilita ya que
  puede confundir a los principiantes.

#   With narrowing, the rest of a buffer is made invisible, as if it weren't
#   there. This is an advantage if, for example, you want to replace a word in
#   one part of a buffer but not in another: you narrow to the part you want
#   and the replacement is carried out only in that section, not in the rest of
#   the buffer. Searches will only work within a narrowed region, not outside
#   of one, so if you are fixing a part of a document, you can keep yourself
#   from accidentally finding parts you do not need to fix by narrowing just to
#   the region you want.  (The key binding for @c{narrow-to-region} is @k{C-x n n}.)
  Con la reduccion, el resto del búfer se hace invisible, como si no estuviera
  alli. Esto es una ventaja si, por ejemplo, se quiere reemplazar una palabra en
  una parte del búfer pero no en otra: limitas la parte que deseas y el
  reemplazo se lleva a cabo solo en esa sección, no en el resto del búfer. Las
  búsquedas solo funcionarán con la región reducida, no fuera de ella, de esta
  forma si estás reparando una parte de un documento, puedes mantener fuera la
  parte que no necesitas. (El atajo asociado a @c{narrow-to-region} es @k{C-x n n}.)

#   However, narrowing does make the rest of the buffer invisible, which can
#   scare people who inadvertently invoke narrowing and think they have deleted
#   a part of their file. Moreover, the @c{undo} command (which is usually
#   bound to @k{C-x u}) does not turn off narrowing (nor should it), so people
#   can become quite desperate if they do not know that they can return the
#   rest of a buffer to visibility with the @c{widen} command.  (The key
#   binding for @c{widen} is @k{C-x n w}.)
  Sin embargo, la reduccion hace invisible el resto del búfer, lo que puede
  asustar a quien invoca inadvertidamente la reduccion y piensa que ha eliminado
  una parte de su fichero. Ademas, el comando @c{undo} (usualmente ligado
  a @k{C-x u}) no desactiva la reduccion (ni debe hacerlo), por lo que las personas
  pueden llegar a desesperarse si no saben que pueden devolver el resto del
  buffer a la visibilidad cor el comando @c{widen} que es @k{C-x n w}.)

#   Narrowing is just as useful to the Lisp interpreter as to a human. Often,
#   an Emacs Lisp function is designed to work on just part of a buffer; or
#   conversely, an Emacs Lisp function needs to work on all of a buffer that
#   has been narrowed. The @c{what-line} function, for example, removes the
#   narrowing from a buffer, if it has any narrowing and when it has finished
#   its job, restores the narrowing to what it was. On the other hand, the
#   @c{count-lines} function uses narrowing to restrict itself to just that
#   portion of the buffer in which it is interested and then restores the
#   previous situation.
  La reduccion es igual de util para el intérprete Lisp como para un humano.
  Con frecuencia, una función Emacs Lisp está diseñada para trabajar solo en
  parte de un búfer; o por el contrario, una función Emacs Lisp necesita
  trabajar en todo un búfer que ha sido reducido. La función @c{what-line}, por
  ejemplo, elimina la reduccion de un búfer, si este tiene alguna reduccion y
  al terminar su trabajo, restaura la reduccion. Por otro lado, la función
  @c{count-lines} utiliza la reduccion para restringirse a sí misma solo a la
  porción del búfer en la que se está interesado y luego restaura la situación
  anterior.

# ** The @c{save-restriction} Special Form
** La forma especial @c{save-restriction}

#    In Emacs Lisp, you can use the @c{save-restriction} special form to keep
#    track of whatever narrowing is in effect, if any. When the Lisp
#    interpreter meets with @c{save-restriction}, it executes the code in the
#    body of the @c{save-restriction} expression, and then undoes any changes
#    to narrowing that the code caused. If, for example, the buffer is
#    narrowed and the code that follows @c{save-restriction} gets rid of the
#    narrowing, @c{save-restriction} returns the buffer to its narrowed region
#    afterwards. In the @c{what-line} command, any narrowing the buffer may
#    have is undone by the @c{widen} command that immediately follows the
#    @c{save-restriction} command. Any original narrowing is restored just
#    before the completion of the function.
   En Emacs Lisp, se puede utilizar la forma especial @c{save-restriction} para
   llevar un registro de cualquier reduccion en efecto. Cuando el intérprete
   Lisp se encuentra con @c{save-restriction}, ejecuta el código en el cuerpo
   de la expresión @c{save-restriction}, y luego deshace cualquier cambio en la
   reduccion causada por el código. Si, por ejemplo, el búfer es reducido y el
   código que sigue al comando @c{save-restriction} se deshace de la reduccion,
   @c{save-restriction} devuelve el búfer a su región reducida.  En el comando
   @c{what-line}, cualquier reduccion del búfer puede anularse por el comando
   @c{widen} inmediatamente despues del comando @c{save-restriction}. Se
   restaura cualquier reduccion original justo antes de finalizar la función.

#    The template for a @c{save-restriction} expression is simple:
   La plantilla para una expresión @c{save-restriction} es simple:

#    ..src > elisp
#      (save-restriction
#        body… )
#    < src..
   ..src > elisp
     (save-restriction
       cuerpo… )
   < src..

#    The body of the @c{save-restriction} is one or more expressions that will
#    be evaluated in sequence by the Lisp interpreter.
   El cuerpo de @c{save-restriction} es una o más expresiones que seran evaluadas
   de forma secuencial por el intérprete Lisp.

#    Finally, a point to note: when you use both @c{save-excursion} and
#    @c{save-restriction}, one right after the other, you should use
#    @c{save-excursion} outermost. If you write them in reverse order, you may
#    fail to record narrowing in the buffer to which Emacs switches after
#    calling @c{save-excursion}. Thus, when written together,
#    @c{save-excursion} and @c{save-restriction} should be written like this:
   Finalmente, un punto a tener en cuenta: cuando utilices @c{save-excursion}
   y @c{save-restriction} a la vez, una detras de la otra, debes utilizar
   @c{save-excursion} primero. Si lo escribes en orden inverso, es posible
   que no registre la reduccion en el búfer al que emacs debe cambiar Emacs
   despues de llamar a @c{save-excursion}. Por lo tanto, cuando escribas a la
   vez @c{save-excursion} y @c{save-restriction} debe ser así:

#    ..src > elisp
#      (save-excursion
#        (save-restriction
#          body…))
#    < src..
   ..src > elisp
     (save-excursion
       (save-restriction
         cuerpo…))
   < src..

#    In other circumstances, when not written together, the @c{save-excursion}
#    and @c{save-restriction} special forms must be written in the order
#    appropriate to the function.
   En otras circunstancias, cuando no se escriban a la vez, las formas
   especiales @c{save-excursion} y @c{save-restriction} deben escribirse en el
   orden adecuado para la función.

#    For example,
   Por ejemplo,

#    ..src > elisp
#      (save-restriction
#        (widen)
#        (save-excursion
#        body…))
#    < src..
   ..src > elisp
     (save-restriction
       (widen)
       (save-excursion
       cuerpo…))
   < src..

# ** @c{what-line}
** @c{what-line}

#    The @c{what-line} command tells you the number of the line in which the
#    cursor is located. The function illustrates the use of the
#    @c{save-restriction} and @c{save-excursion} commands. Here is the
#    original text of the function:
   El comando @c{what-line} informa el número de la línea en la que el cursor
   esta colocado. La función ilustra el uso de los comandos @c{save-restriction}
   y @c{save-excursion}. Aquí está el texto original de la función:

#    ..src > elisp
#      (defun what-line ()
#        "Print the current line number (in the buffer) of point."
#        (interactive)
#        (save-restriction
#          (widen)
#          (save-excursion
#            (beginning-of-line)
#            (message "Line %d"
#                     (1+ (count-lines 1 (point)))))))
#    < src..
   ..src > elisp
     (defun what-line ()
       "Imprime el numero de linea actual (en el bufer) del punto."
       (interactive)
       (save-restriction
         (widen)
         (save-excursion
           (beginning-of-line)
           (message "Line %d"
                    (1+ (count-lines 1 (point)))))))
   < src..

#    (In recent versions of GNU Emacs, the @c{what-line} function has been
#    expanded to tell you your line number in a narrowed buffer as well as your
#    line number in a widened buffer. The recent version is more complex than
#    the version shown here. If you feel adventurous, you might want to look
#    at it after figuring out how this version works. You will probably need
#    to use @k{C-h f} @%c(describe-function). The newer version uses a
#    conditional to determine whether the buffer has been narrowed.
   (En versiones recientes de GNU Emacs, la función @c{what-line} se ha ampliado
   para decirte el numero de linea en un búfer reducido, asi como el número
   de línea en un búfer extendido. La versión reciente es más compleja que la
   versión que se muestra aqui. Si te sientes aventurero, puede que quieras
   verla despues de averiguar como funciona esta version. Probablemente
   necesites utilizar @k{C-h f} @%c(describe-function). La nueva versión
   utiliza un condicional para determinar si se ha reducido el búfer.

#    (Also, it uses @c{line-number-at-pos}, which among other simple
#    expressions, such as @c{(goto-char (point-min))}, moves point to the
#    beginning of the current line with @c{(forward-line 0)} rather than
#    @c{beginning-of-line}.)
   (También, utiliza @c{line-number-at-pos}, que entre otras expresiones
   sencillas, como @c{(goto-char (point-min))}, mueve el punto al inicio de la
   línea actual con @c{(forward-line 0)} en lugar de @c{beginning-of-line}.)

#    The @c{what-line} function as shown here has a documentation line and is
#    interactive, as you would expect. The next two lines use the functions
#    @c{save-restriction} and @c{widen}.
   La función @c{what-line} que se muestra aqui tiene una línea de documentación
   y es interactiva, como es de esperar. Las dos líneas siguientes utilizan las
   funciones @c{save-restriction} y @c{widen}.

#    The @c{save-restriction} special form notes whatever narrowing is in
#    effect, if any, in the current buffer and restores that narrowing after
#    the code in the body of the @c{save-restriction} has been evaluated.
   La forma especial @c{save-restriction} observa cualquier reduccion activa en
   el buffer actual y restaura la reduccion despues de evaluar el código de su
   cuerpo.

#    The @c{save-restriction} special form is followed by @c{widen}. This
#    function undoes any narrowing the current buffer may have had when
#    @c{what-line} was called.  (The narrowing that was there is the narrowing
#    that @c{save-restriction} remembers.)  This widening makes it possible for
#    the line counting commands to count from the beginning of the buffer.
#    Otherwise, they would have been limited to counting within the accessible
#    region. Any original narrowing is restored just before the completion of
#    the function by the @c{save-restriction} special form.
   La forma especial @c{save-restriction} es seguida por @c{widen}. Esta función
   deshace cualquier reduccion que pudiera haber tenido el búfer actual cuando se
   llama a @c{what-line}. (La reduccion que estaba alli es la reduccion que
   @c{save-restriction} recuerda.) Esta ampliación hace posible que los comandos
   para el conteo de lineas cuenten desde el inicio del búfer. De lo contrario,
   se habría limitado a contar dentro de la región accesible. Cualquier
   reduccion original se restaura justo antes de completar la funcion por la
   forma especial @c{save-restriction}.

#    The call to @c{widen} is followed by @c{save-excursion}, which saves the
#    location of the cursor (i.e., of point) and of the mark, and restores them
#    after the code in the body of the @c{save-excursion} uses the
#    @c{beginning-of-line} function to move point.
   La llamada a @c{widen} es seguida por @c{save-excursion}, que guarda la
   posición del cursor (es decir, el punto) y la marca, y los restaura después
   de que el código en el cuerpo de @c{save-excursion} utiliza la
   función @c{beginning-of-line} para mover el punto.

#    (Note that the @c{(widen)} expression comes between the
#    @c{save-restriction} and @c{save-excursion} special forms. When you write
#    the two @c{save-…} expressions in sequence, write @c{save-excursion}
#    outermost.)
   (Ten en cuenta que la expresión @c{(widen)} ocurre entre las formas
   especiales @c{save-restriction} y @c{save-excursion}. Cuando escribas las dos
   expresiones @c{save-…} consecutivamente, escribe @c{save-excursion} primero.)

#    The last two lines of the @c{what-line} function are functions to count
#    the number of lines in the buffer and then print the number in the echo
#    area.
   Las dos últimas líneas de la función @c{what-line} son funciones para contar
   el número de líneas en el búfer y luego imprimir el número en el área de eco.

#    ..src > elisp
#      (message "Line %d"
#               (1+ (count-lines 1 (point)))))))
#    < src..
   ..src > elisp
     (message "Line %d"
              (1+ (count-lines 1 (point)))))))
   < src..

#    The @c{message} function prints a one-line message at the bottom of the
#    Emacs screen. The first argument is inside of quotation marks and is
#    printed as a string of characters. However, it may contain a @'c{%d}
#    expression to print a following argument.  @'c{%d} prints the argument as a
#    decimal, so the message will say something such as @'c{Line 243}.
   La función @c{message} imprime un mensaje de una línea en la parte inferior
   de la pantalla de Emacs. El primer argumento esta dentro de comillas y se
   imprime como una cadena de caracteres. Sin embargo, contiene una expresión
   @'c{%d} para imprimir el siguiente argumento. @'c{%d} imprime el argumento como
   un decimal, por lo que el mensaje dirá algo como @'c{Línea 243}.

#    The number that is printed in place of the @'{%d} is computed by the last
#    line of the function:
   El número que se imprime en lugar del @'{%d} se calcula por la última línea
   de la función:

#    ..src > elisp
#      (1+ (count-lines 1 (point)))
#    < src..
   ..src > elisp
     (1+ (count-lines 1 (point)))
   < src..

#    What this does is count the lines from the first position of the buffer,
#    indicated by the @c{1}, up to @c{(point)}, and then add one to that
#    number.  (The @c{1+} function adds one to its argument.)  We add one to it
#    because line 2 has only one line before it, and @c{count-lines} counts
#    only the lines @e{before} the current line.
   Lo que esto hace es contar las líneas desde la primer posición del búfer
   indicada por el @c{1}, hasta @c{(point)}, y luego sumar uno a este número.
   (La función @c{1+} suma uno a su argumento.) Se suma uno porque la línea 2
   tiene solo una línea antes de ella, y @c{count-lines} cuenta solo las líneas
   @e{antes} de la línea actual.

#    After @c{count-lines} has done its job, and the message has been printed
#    in the echo area, the @c{save-excursion} restores point and mark to their
#    original positions; and @c{save-restriction} restores the original
#    narrowing, if any.
   Después que @c{count-lines} termina su trabajo, y se imprime el mensaje en el
   área de eco, la función @c{save-excursion} restaura el punto y marca a sus
   posiciones originales; y @c{save-restriction} restaura la reduccion original,
   si la hubiera.

# ** Exercise with Narrowing
** Ejercicio con Reduccion

#    Write a function that will display the first 60 characters of the current
#    buffer, even if you have narrowed the buffer to its latter half so that
#    the first line is inaccessible. Restore point, mark, and narrowing. For
#    this exercise, you need to use a whole potpourri of functions, including
#    @c{save-restriction}, @c{widen}, @c{goto-char}, @c{point-min},
#    @c{message}, and @c{buffer-substring}.
   Escribe una función que muestre los primeros 60 caracteres del búfer actual,
   incluso si has reducido el búfer a la mitad de modo que la primer línea sea
   inaccesible. Restaura el punto, marca y la reduccion. Para este ejercicio,
   necesitas utilizar todo un popurri de funciones, incluyendo
   @c{save-restriction}, @c{widen}, @c{goto-char}, @c{point-min}, @c{message}, y
   @c{buffer-substring}.

#    (@c{buffer-substring} is a previously unmentioned function you will have to
#    investigate yourself; or perhaps you will have to use
#    @c{buffer-substring-no-properties} or @c{filter-buffer-substring} …, yet
#    other functions. Text properties are a feature otherwise not discussed
#    here. See Section @l{elisp.html#Text Properties<>Text Properties} in @e{The GNU Emacs Lisp
#    Reference Manual}.)
   (@c{buffer-substring} es una función que aun no se menciona, tendrás que
   investigarla por tu cuenta; o quizás tengas que utilizar
   @c{buffer-substring-no-properties} o @c{filter-buffer-substring} …, u otras
   funciones. Las propiedades de texto son una funcionalidad que no sera
   discutida aquí. Consulta la Seccion @l{elisp.html#Text Properties<>Propiedades de
   Texto} en @e(El Manual de Referencia de Emacs Lisp).)

#    Additionally, do you really need @c{goto-char} or @c{point-min}?  Or can
#    you write the function without them?
   Además, ¿realmente se necesita @c{goto-char} o @c{point-min}?  ¿O se puede
   escribir la función sin ellas?

# * @c{car}, @c{cdr}, @c{cons}: Fundamental Functions
* @c{car}, @c{cdr}, @c{cons}: Funciones fundamentales

#   In Lisp, @c{car}, @c{cdr}, and @c{cons} are fundamental functions. The
#   @c{cons} function is used to construct lists, and the @c{car} and @c{cdr}
#   functions are used to take them apart.
  En Lisp, @c{car}, @c{cdr}, y @c{cons} son funciones fundamentales. La función
  @c{cons} se utiliza para construir listas, y las funciones @c{car} y @c{cdr}
  se utilizan para desmontarlas.

#   In the walk through of the @c{copy-region-as-kill} function, we will see
#   @c{cons} as well as two variants on @c{cdr}, namely, @c{setcdr} and
#   @c{nthcdr}.  (See Section @l{#@c{copy-region-as-kill}}.)
  En el recorrido a través de la función @c{copy-region-as-kill}, veremos @c{cons},
  asi como dos variantes de @c{cdr}, llamadas @c{setcdr} y @c{nthcdr}. (Consulta la
  Sección @l{#@c{copy-region-as-kill}}.)

#   The name of the @c{cons} function is not unreasonable: it is an
#   abbreviation of the word ‘construct’. The origins of the names for @c{car}
#   and @c{cdr}, on the other hand, are esoteric: @c{car} is an acronym from
#   the phrase @'b(Contents of the Address part of the Register); and @c{cdr}
#   (pronounced ‘could-er’) is an acronym from the phrase @'b(Contents of the
#   Decrement part of the Register). These phrases refer to specific pieces of
#   hardware on the very early computer on which the original Lisp was
#   developed. Besides being obsolete, the phrases have been completely
#   irrelevant for more than 25 years to anyone thinking about Lisp.
#   Nonetheless, although a few brave scholars have begun to use more
#   reasonable names for these functions, the old terms are still in use. In
#   particular, since the terms are used in the Emacs Lisp source code, we will
#   use them in this introduction.
  El nombre de la función @c{cons} no es irazonable: es una abreviatura de la
  palabra ‘construct’ @%i(construir). Por otra parte, el origen de los nombres
  @c{car} y @c{cdr}, es esoterico: @c{car} es un acrónimo de la frase @'b(Contents
  of the Address part of the Register) @%i(Contenidos de las Direcciónes parte
  del Registro); y @c{cdr} (pronunciado ‘could-er’) es un acrónimo de la frase
  @'b(Contents of the Decrement part of the Register) @%i(Contenidos de la parte de
  Decremento del Registro). Estas frases se refieren a piezas específicas de
  hardware en el ordenador en el que se desarrollo el Lisp original. Ademas de
  ser obsoletas, las frases han sido completamente irrelevantes por más de 25
  años para cualquiera que piense en Lisp. No obstante, aunque algunos pocos
  académicos valientes han empezado a utilizar nombres más razonables para estas
  funciones, los viejos términos aun continuan en uso. En particular, dado que los
  términos se utilizan en el código fuente de Emacs Lisp, los usaremos en esta
  introducción.

# ** @c{car} and @c{cdr}
** @c{car} y @c{cdr}

#    The @c{car} of a list is, quite simply, the first item in the list. Thus
#    the @c{car} of the list @c{(rose violet daisy buttercup)} is @c{rose}.
   El @c{car} de una lista es sencillamente, el primer elemento de la lista. De
   este modo, el @c{car} de la lista @c{(rosa violeta margarita tulipan)} es
   @c{rosa}.

#    If you are reading this in Info in GNU Emacs, you can see this by
#    evaluating the following:
   Si estás leyendo esto dentro de GNU Emacs, puedes verlo evaluando lo siguiente:

#    ..src > elisp
#      (car '(rose violet daisy buttercup))
#    < src..
   ..src > elisp
     (car '(rosa violeta margarita tulipan))
   < src..

#    After evaluating the expression, @c{rose} will appear in the echo area.
   Después de evaluar la expresión, aparecerá @c{rosa} en el área de eco.

#    Clearly, a more reasonable name for the @c{car} function would be
#    @c{first} and this is often suggested.
   Claramente, un nombre más razonable para la función @c{car} sería @c{first} y
   esto es con frecuencia lo que se sugiere.

#    @c{car} does not remove the first item from the list; it only reports what
#    it is. After @c{car} has been applied to a list, the list is still the
#    same as it was. In the jargon, @c{car} is ‘non-destructive’. This
#    feature turns out to be important.
   @c{car} no elimina el primer elemento de la lista; solo informa de lo que
   es. Después de aplicar @c{car} a una lista, la lista sigue siendo la misma
   que antes. En la jerga, @c{car} es ‘no destructiva’. Esta caracteristica
   resulta ser importante.

#    The @c{cdr} of a list is the rest of the list, that is, the @c{cdr}
#    function returns the part of the list that follows the first item. Thus,
#    while the @c{car} of the list @c{'(rose violet daisy buttercup)} is
#    @c{rose}, the rest of the list, the value returned by the @c{cdr}
#    function, is @c{(violet daisy buttercup)}.
   El @c{cdr} de una lista es el resto de la lista, es decir, la función @c{cdr}
   devuelve la parte de la lista que sigue al primer elemento. Por lo tanto,
   mientras que el @c{car} de la lista @c{'(rosa violeta margarita tulipan)} es
   @c{rosa}, el resto de la lista, el valor devuelto por la función @c{cdr}, es
   @c{(violeta margarita tulipan)}.

#    You can see this by evaluating the following in the usual way:
   Puedes ver esto evaluando lo siguiente del modo habitual:

#    ..src > elisp
#      (cdr '(rose violet daisy buttercup))
#    < src..
   ..src > elisp
     (cdr '(rosa violeta margarita tulipan))
   < src..

#    When you evaluate this, @c{(violet daisy buttercup)} will appear in the
#    echo area.
   Al evaluar esto, aparece @c{(violeta margarita tulipan)} en el área de eco.

#    Like @c{car}, @c{cdr} does not remove any elements from the list––it just
#    returns a report of what the second and subsequent elements are.
   Al igual que @c{car}, @c{cdr} no elimina los elementos de la
   lista––simplemente devuelve un informe de lo que son el segundo y los
   elementos siguientes.

#    Incidentally, in the example, the list of flowers is quoted. If it were
#    not, the Lisp interpreter would try to evaluate the list by calling
#    @c{rose} as a function. In this example, we do not want to do that.
   A propositio, en el ejemplo, se cita la lista de las flores. De otra forma, el
   intérprete Lisp intentaría evaluar la lista llamando a @c{rosa} como una
   función. En este ejemplo, no queremos hacer esto.

#    Clearly, a more reasonable name for @c{cdr} would be @c{rest}.
   Claramente, un nombre más razonable para @c{cdr} sería @c{rest} @%i(resto).

#    (There is a lesson here: when you name new functions, consider very
#    carefully what you are doing, since you may be stuck with the names for
#    far longer than you expect. The reason this document perpetuates these
#    names is that the Emacs Lisp source code uses them, and if I did not use
#    them, you would have a hard time reading the code; but do, please, try to
#    avoid using these terms yourself. The people who come after you will be
#    grateful to you.)
   (Hay una lección aquí: Cuando des nombre a nuevas funciones, considera muy
   cuidadosamente lo que estes haciendo, ya que puedes adherirte a los nombres
   mas tiempo del esperado. La razón por la que este documento perpetúa estos
   nombres se debe a que el código fuente de Emacs Lisp los utiliza, y de no usarlos,
   tendrias dificultades para leer el codigo; por favor, intenta evitar usar
   estos términos por tu cuenta. Las personas que vengan después te lo
   agradecerán.

#    When @c{car} and @c{cdr} are applied to a list made up of symbols, such as
#    the list @c{(pine fir oak maple)}, the element of the list returned by the
#    function @c{car} is the symbol @c{pine} without any parentheses around it.
#    @c{pine} is the first element in the list. However, the @c{cdr} of the
#    list is a list itself, @c{(fir oak maple)}, as you can see by evaluating
#    the following expressions in the usual way:
   Cuando se aplican @c{car} y @c{cdr} a una lista compuesta por símbolos, como
   la lista @c{(pino abeto roble arce)}, el elemento de la lista devuelto por la
   función @c{car} es el símbolo @c{pino} sin ningun paréntesis alrededor.
   @c{pino} es el primer elemento en la lista. Sin embargo, el @c{cdr} de la
   lista es una lista en si misma, @c{(abeto roble arce)}, como puedes observar al
   evaluar las siguientes expresiones:

#    ..src > elisp
   ..src > elisp
#      (car '(pine fir oak maple))
     (car '(pino abeto roble arce))

#      (cdr '(pine fir oak maple))
     (cdr '(pino abeto roble arce))
#    < src..
   < src..

#    On the other hand, in a list of lists, the first element is itself a list.
#    @c{car} returns this first element as a list. For example, the following
#    list contains three sub-lists, a list of carnivores, a list of herbivores
#    and a list of sea mammals:
   Por otro lado, en una lista de listas, el primer elemento es en sí mismo una
   lista. @c{car} devuelve este primer elemento como una lista. Por ejemplo, la
   siguiente lista contiene tres sub-listas, una lista de carnívoros, una lista
   de herbívoros y una lista de mamíferos:

#    ..src > elisp
#      (car '((lion tiger cheetah)
#             (gazelle antelope zebra)
#             (whale dolphin seal)))
#    < src..
   ..src > elisp
     (car '((leon tigre leopardo)
            (gacela antilope cebra)
            (ballena delfin foca)))
   < src..

#    In this example, the first element or @c{car} of the list is the list of
#    carnivores, @c{(lion tiger cheetah)}, and the rest of the list is
#    @c{((gazelle antelope zebra) (whale dolphin seal))}.
   En este ejemplo, el primer elemento de @c{car} de la lista es la lista de
   carnívoros, @c{(leon tigre leopardo)}, y el resto de la lista es
   @c{((gacela antilope cebra) (ballena delfin foca))}.

#    ..src > elisp
#      (cdr '((lion tiger cheetah)
#             (gazelle antelope zebra)
#             (whale dolphin seal)))
#    < src..
   ..src > elisp
     (cdr '((leon tigre leopardo)
            (gacela antilope cebra)
            (ballena delfin foca)))
   < src..

#    It is worth saying again that @c{car} and @c{cdr} are
#    non-destructive––that is, they do not modify or change lists to which they
#    are applied. This is very important for how they are used.
   vale la pena decir nuevamente que @c{car} y @c{cdr} son no destructivos––es
   dicir, no modifican ni cambian las listas a las que se aplican. Esto es muy
   importante para la forma en que se utilizan.

#    Also, in the first chapter, in the discussion about atoms, I said that in
#    Lisp, “certain kinds of atom, such as an array, can be separated into
#    parts; but the mechanism for doing this is different from the mechanism
#    for splitting a list. As far as Lisp is concerned, the atoms of a list
#    are unsplittable.”  (See Section @l{#Lisp Atoms}.)  The @c{car} and @c{cdr}
#    functions are used for splitting lists and are considered fundamental to
#    Lisp. Since they cannot split or gain access to the parts of an array, an
#    array is considered an atom. Conversely, the other fundamental function,
#    @c{cons}, can put together or construct a list, but not an array.  (Arrays
#    are handled by array-specific functions. See Section
#    @l{elisp.html#Arrays<>Arrays} in @e{The GNU Emacs Lisp Reference Manual}.)
   En el primer capítulo, en la discusión sobre los átomos, dije que en Lisp,
   “ciertos tipos de átomos, como un arreglo, pueden ser separados en partes;
   pero el mecanismo para hacer esto es diferente del mecanismo para separar una
   lista. Para Lisp, los átomos de una lista son indivisibles.” (Consulta la Seccion
   @l{#Átomos Lisp}.) Las funciones @c{car} y @c{cdr} se utilizan para dividir
   listas y se consideran fundamentales en Lisp. Ya que no se puede dividir o
   tener acceso a las partes de un arreglo, un arreglo se considera un
   átomo. Por otro lado, la otra función fundamental, @c{cons}, puede armar o
   construir una lista, pero no un arreglo. (Los arreglos se manejan mediante
   funciones especificas de arreglos. Consulta la Seccion
   @l{elisp.html#Arrays<>Arreglos} en el @e(El Manual de Referencia de GNU Emacs
   Lisp).)

# ** @c{cons}
** @c{cons}

#    The @c{cons} function constructs lists; it is the inverse of @c{car} and
#    @c{cdr}. For example, @c{cons} can be used to make a four element list
#    from the three element list, @c{(fir oak maple)}:
   La función @c{cons} construye listas; que es lo opuesto a @c{car} y @c{cdr}.
   Por ejemplo, se puede utilizar @c{cons} para hacer una lista de cuatro elementos
   de la lista de tres elementos, @c{(abeto roble arce)}:

#    ..src > elisp
#      (cons 'pine '(fir oak maple))
#    < src..
   ..src > elisp
     (cons 'pino '(abeto roble arce))
   < src..

#    After evaluating this list, you will see
   Después de evaluar esto, veras

#    ..src > elisp
#      (pine fir oak maple)
#    < src..
   ..src > elisp
     (pino abeto roble arce)
   < src..

#    appear in the echo area.  @c{cons} causes the creation of a new list in
#    which the element is followed by the elements of the original list.
   aparecer en el área de eco. @c{cons} produce una nueva lista en la que el elemento es
   seguido por los elementos de la lista original.

#    We often say that ‘@c{cons} puts a new element at the beginning of a list;
#    it attaches or pushes elements onto the list’, but this phrasing can be
#    misleading, since @c{cons} does not change an existing list, but creates a
#    new one.
   Con frecuencia decimos que ‘@c{cons} coloca un nuevo elemento al principio de
   una lista; que agrega o empuja el elemento en la lista’, pero esta frase
   puede ser engañosa, ya que @c{cons} no modifica una lista existente, sino que
   crea una nueva.

#    Like @c{car} and @c{cdr}, @c{cons} is non-destructive.
   Al igual que @c{car} y @c{cdr}, @c{cons} es no destructivo.

#    @c{cons} must have a list to attach to.@n{9} You cannot start from
#    absolutely nothing. If you are building a list, you need to provide at
#    least an empty list at the beginning. Here is a series of @c{cons}
#    expressions that build up a list of flowers. If you are reading this in
#    Info in GNU Emacs, you can evaluate each of the expressions in the usual
#    way; the value is printed in this text after @'{⇒}, which you may read as
#    ‘evaluates to’.
   @c{cons} debe tener una lista a unir.@n{9} No puedes iniciar de la nada
   absoluta. Si estás construyendo una lista, es necesario proporcionar al menos
   una lista vacía al inicio. Aquí hay una serie de expresiones @c{cons} que
   construyen una lista de flores. Si está leyendo esto en GNU Emacs, puedes
   evaluar cada una de las expresiones para corroborar el resultado.

#    ..srci > elisp
#      > (cons 'buttercup ())
#      (buttercup)
#      > (cons 'daisy '(buttercup))
#      (daisy buttercup)
#      > (cons 'violet '(daisy buttercup))
#      (violet daisy buttercup)
#      > (cons 'rose '(violet daisy buttercup))
#      (rose violet daisy buttercup)
#    < srci..
   ..srci > elisp
     > (cons 'tulipan ())
     (tulipan)
     > (cons 'margarita '(tulipan))
     (margarita tulipan)
     > (cons 'violeta '(margarita tulipan))
     (violeta margarita tulipan)
     > (cons 'rosa '(violeta margarita tulipan))
     (rosa violeta margarita tulipan)
   < srci..

#    In the first example, the empty list is shown as @c{()} and a list made up
#    of @c{buttercup} followed by the empty list is constructed. As you can
#    see, the empty list is not shown in the list that was constructed. All
#    that you see is @c{(buttercup)}. The empty list is not counted as an
#    element of a list because there is nothing in an empty list. Generally
#    speaking, an empty list is invisible.
   En el primer ejemplo, la lista vacía se muestra como @c{()} y se construye
   una lista compuesta por @c{tulipan} seguida por la lista vacía. Como puedes
   ver, la lista vacía no se muestra en la lista que se construyo. Todo lo que
   ves es @c{(tulipan)}. La lista vacía no cuenta como un elemento de una
   lista porque no hay nada en una lista vacía. En terminos generales, una lista
   vacía es invisible.

#    The second example, @c{(cons 'daisy '(buttercup))} constructs a new, two
#    element list by putting @c{daisy} in front of @c{buttercup}; and the third
#    example constructs a three element list by putting @c{violet} in front of
#    @c{daisy} and @c{buttercup}.
   El segundo ejemplo, @c{(cons 'margarita '(tulipan))} construye una nueva
   lista de dos elemento colocando @c{margarita} delante de @c{tulipan}; y el
   tercer ejemplo construye una lista de tres elementos colocando @c{violeta}
   delante de @c{margarita} y @c{tulipan}.

# *** Find the Length of a List: @c{length}
*** Descubrir la longitud de una lista: @c{length}

#     You can find out how many elements there are in a list by using the Lisp
#     function @c{length}, as in the following examples:
    Puedes averiguar cuántos elementos hay en una lista utilizando la función
    Lisp @c{length}, como en los siguientes ejemplos:

#     ..srci > elisp
#       > (length '(buttercup))
#       1
#       > (length '(daisy buttercup))
#       2
#       > (length (cons 'violet '(daisy buttercup)))
#       3
#     < srci..
    ..srci > elisp
      > (length '(tulipan))
      1
      > (length '(margarita tulipan))
      2
      > (length (cons 'violeta '(margarita tulipan)))
      3
    < srci..

#     In the third example, the @c{cons} function is used to construct a three
#     element list which is then passed to the @c{length} function as its
#     argument.
    En el tercer ejemplo, la función @c{cons} se utiliza para construir una
    lista de tres elementos que se pasa como argumento a la función @c{length}.

#     We can also use @c{length} to count the number of elements in an empty
#     list:
    También podemos utilizar @c{length} para contar el número de elementos en
    una lista vacía:

#     ..srci > elisp
#       > (length ())
#       0
#     < srci..
    ..srci > elisp
      > (length ())
      0
    < srci..

#     As you would expect, the number of elements in an empty list is zero.
    Como era de esperar, el número de elementos en una lista vacía es cero.

#     An interesting experiment is to find out what happens if you try to find
#     the length of no list at all; that is, if you try to call @c{length}
#     without giving it an argument, not even an empty list:
    Un experimento interesante es averiguar qué ocurre si se intenta encontrar
    la longitud de ninguna lista; es decir, si se intenta llamar a @c{length}
    sin darle un argumento, ni siquiera una lista vacía:

#     ..src > elisp
#       (length )
#     < src..
    ..src > elisp
      (length )
    < src..

#     What you see, if you evaluate this, is the error message
    La que se ve, si evalúas esto, es el mensaje de error

#     ..example >
#       Lisp error: (wrong-number-of-arguments length 0)
#     < example..
    ..example >
      Lisp error: (wrong-number-of-arguments length 0)
    < example..

#     This means that the function receives the wrong number of arguments,
#     zero, when it expects some other number of arguments. In this case, one
#     argument is expected, the argument being a list whose length the function
#     is measuring.  (Note that @e{one} list is @e{one} argument, even if the
#     list has many elements inside it.)
    Esto significa que la función recibe un número incorrecto de argumentos,
    cero, cuando se espera otro número de argumentos. En este caso, se
    espera un argumento, el argumento es una lista cuya longitud mide la
    función. (Ten en cuenta que @e{una} lista es @e{un} argumento, incluso si la
    lista tiene muchos elementos en su interior.)

#     The part of the error message that says @'{length} is the name of the
#     function.
    La parte del mensaje de error que dice @'{length} es el nombre de la
    función.

# ** @c{nthcdr}
** @c{nthcdr}

#    The @c{nthcdr} function is associated with the @c{cdr} function. What it
#    does is take the @c{cdr} of a list repeatedly.
   La función @c{nthcdr} esta asociada a la función @c{cdr}. Lo que hace es tomar
   el @c{cdr} de una lista repetidamente.

#    If you take the @c{cdr} of the list @c{(pine fir oak maple)}, you will be
#    returned the list @c{(fir oak maple)}. If you repeat this on what was
#    returned, you will be returned the list @c{(oak maple)}.  (Of course,
#    repeated @c{cdr}ing on the original list will just give you the original
#    @c{cdr} since the function does not change the list. You need to
#    evaluate the @c{cdr} of the @c{cdr} and so on.)  If you continue this,
#    eventually you will be returned an empty list, which in this case, instead
#    of being shown as @c{()} is shown as @c{nil}.
   Si tomas el @c{cdr} de la lista @c{(pino abeto roble arce)}, te devuelve la
   lista @c{(abeto roble arce)}. Si repites esto al retorno, devolverá la lista
   @c{(roble arce)}. (Por supuesto, repetir @c{cdr} en la lista original solo
   dará el @c{cdr} original, ya que la función no cambia la lista. Necesitas
   evaluar el @c{cdr} del @c{cdr} y así sucesivamente.) Si esto contiúa,
   finalmente se devuelve una lista vacía, que en este caso, en vez de mostrarse
   como @c{()} se muestra como @c{nil}.

#    For review, here is a series of repeated @c{cdr}s.
   Para comprobarlo, aquí hay una serie de @c{cdr}s repetidos.

#    ..srci > elisp
#      > (cdr '(pine fir oak maple))
#      (fir oak maple)
#      > (cdr '(fir oak maple))
#      (oak maple)
#      > (cdr '(oak maple))
#      (maple)
#      > (cdr '(maple))
#      nil
#      > (cdr 'nil)
#      nil
#      > (cdr ())
#      nil
#    < srci..
   ..srci > elisp
     > (cdr '(pino abeto roble arce))
     (abeto roble arce)
     > (cdr '(abeto roble arce))
     (roble arce)
     > (cdr '(roble arce))
     (arce)
     > (cdr '(arce))
     nil
     > (cdr 'nil)
     nil
     > (cdr ())
     nil
   < srci..

#    You can also do several @c{cdr}s without printing the values in between,
#    like this:
   También puedes hacer varios @c{cdr}s sin imprimir los valores intermedios, de
   esta forma:

#    ..srci > elisp
#      > (cdr (cdr '(pine fir oak maple)))
#      (oak maple)
#    < srci..
   ..srci > elisp
     > (cdr (cdr '(pino abeto roble arce)))
     (roble arce)
   < srci..

#    In this example, the Lisp interpreter evaluates the innermost list first.
#    The innermost list is quoted, so it just passes the list as it is to the
#    innermost @c{cdr}. This @c{cdr} passes a list made up of the second and
#    subsequent elements of the list to the outermost @c{cdr}, which produces a
#    list composed of the third and subsequent elements of the original list.
#    In this example, the @c{cdr} function is repeated and returns a list that
#    consists of the original list without its first two elements.
   En este ejemplo, el intérprete Lisp primero evalúa la lista mas interna. La
   lista mas interna se cita, por lo que solo pasa la lista tal cual al @c{cdr}
   interno. Este @c{cdr} pasa una lista formada por el segundo y los subsiguientes
   elementos de la lista al @c{cdr} externo, que produce una lista compuesta del
   tercer y los subsiguientes elementos de la lista original. En este ejemplo, la
   función @c{cdr} se repite y devuelve una lista que consiste en la lista
   original sin sus primeros dos elementos.

#    The @c{nthcdr} function does the same as repeating the call to @c{cdr}.
#    In the following example, the argument 2 is passed to the function
#    @c{nthcdr}, along with the list, and the value returned is the list
#    without its first two items, which is exactly the same as repeating
#    @c{cdr} twice on the list:
   La función @c{nthcdr} hace lo mismo que repetir la llamada a @c{cdr}. En el
   siguiente ejemplo, el argumento 2 se pasa a la función @c{nthcdr}, junto con
   la lista, y el valor devuelto es la lista sin sus dos primeros elementos, que
   es exactamente lo mismo que repetir dos veces @c{cdr} en la lista:

#    ..srci > elisp
#      > (nthcdr 2 '(pine fir oak maple))
#      (oak maple)
#    < srci..
   ..srci > elisp
     > (nthcdr 2 '(pino abeto roble arce))
     (roble arce)
   < srci..

#    Using the original four element list, we can see what happens when various
#    numeric arguments are passed to @c{nthcdr}, including 0, 1, and 5:
   Utilizando la lista original de cuatro elementos, podemos ver qué ocurre
   cuando se pasan varios argumentos numéricos a @c{nthcdr}, incluyendo 0,
   1, y 5:

#    ..srci > elisp
#      > ;; Leave the list as it was.
#      > (nthcdr 0 '(pine fir oak maple))
#      (pine fir oak maple)
#      > ;; Return a copy without the first element.
#      > (nthcdr 1 '(pine fir oak maple))
#      (fir oak maple)
#      > ;; Return a copy of the list without three elements.
#      > (nthcdr 3 '(pine fir oak maple))
#      (maple)
#      > ;; Return a copy lacking all four elements.
#      > (nthcdr 4 '(pine fir oak maple))
#      nil
#      > ;; Return a copy lacking all elements.
#      > (nthcdr 5 '(pine fir oak maple))
#      nil
#    < srci..
   ..srci > elisp
     > ;; Deja la lista como estaba.
     > (nthcdr 0 '(pino abeto roble arce))
     (pino abeto roble arce)
     > ;; Regresa una copia sin el primer elemento.
     > (nthcdr 1 '(pino abeto roble arce))
     (abeto roble arce)
     > ;; Regresa una copia de la lista sin tres elementos.
     > (nthcdr 3 '(pino abeto roble arce))
     (arce)
     > ;; Regresa una copia sin los cuatro elementos.
     > (nthcdr 4 '(pino abeto roble arce))
     nil
     > ;; Regresa una copia sin todos los elementos.
     > (nthcdr 5 '(pino abeto roble arce))
     nil
   < srci..

# ** @c{nth}
** @c{nth}

#    The @c{nthcdr} function takes the @c{cdr} of a list repeatedly. The
#    @c{nth} function takes the @c{car} of the result returned by @c{nthcdr}.
#    It returns the Nth element of the list.
   La función @c{nthcdr} toma el @c{cdr} de una lista repetidamente. La función
   @c{nth} toma el @c{car} del resultado devuelto por @c{nthcdr}. Devuelve el
   enesimo elemento de la lista.

#    Thus, if it were not defined in C for speed, the definition of @c{nth}
#    would be:
   Por lo tanto, si @c{nth} no estubiera definido en C por velocidad, su
   definición sería:

#    ..src > elisp
#      (defun nth (n list)
#        "Returns the Nth element of LIST.
#      N counts from zero. If LIST is not that long, nil is returned."
#        (car (nthcdr n list)))
#    < src..
   ..src > elisp
     (defun nth (n list)
       "Devuelve el N-esimo elemento de la lista.
     N cuenta apartir de cero. Si LIST no es tan largo, devuelve nil."
       (car (nthcdr n list)))
   < src..

#    (Originally, @c{nth} was defined in Emacs Lisp in @f{subr.el}, but its
#    definition was redone in C in the 1980s.)
   (Originalmente, @c{nth} se definio en Emacs Lisp dentro de @f{subr.el}, pero
   su definición fué rehecha en C en la decada de 1980.)

#    The @c{nth} function returns a single element of a list. This can be very
#    convenient.
   La función @c{nth} devuelve un solo elemento de una lista. Esto puede ser muy
   conveniente.

#    Note that the elements are numbered from zero, not one. That is to say,
#    the first element of a list, its @c{car} is the zeroth element. This is
#    called ‘zero-based’ counting and often bothers people who are accustomed
#    to the first element in a list being number one, which is ‘one-based’.
   Observa que los elementos estan numerados apartir del cero, no de
   uno. Es decir, el primer elemento de una lista, su @c{car} es el elemento
   cero. Esto se llama contar ‘basado en cero’ y con frecuencia molesta a las
   personas que estan acostumbradas a que el primer elemento de una lista sea el
   número uno, que es ‘basado en uno’.

#    For example:
   Por ejemplo:

#    ..srci > elisp
#      > (nth 0 '("one" "two" "three"))
#      "one"
#      > (nth 1 '("one" "two" "three"))
#      "two"
#    < srci..
   ..srci > elisp
     > (nth 0 '("uno" "dos" "tres"))
     "uno"
     > (nth 1 '("uno" "dos" "tres"))
     "dos"
   < srci..

#    It is worth mentioning that @c{nth}, like @c{nthcdr} and @c{cdr}, does not
#    change the original list––the function is non-destructive. This is in
#    sharp contrast to the @c{setcar} and @c{setcdr} functions.
   Vale la pena mencionar que @c{nth}, al igual que @c{nthcdr} y @c{cdr}, no
   modifica la lista original––la función es no destructiva. Esto contrasta
   fuertemente con las funciones @c{setcar} y @c{setcdr}.

# ** @c{setcar}
** @c{setcar}

#    As you might guess from their names, the @c{setcar} and @c{setcdr}
#    functions set the @c{car} or the @c{cdr} of a list to a new value. They
#    actually change the original list, unlike @c{car} and @c{cdr} which leave
#    the original list as it was. One way to find out how this works is to
#    experiment. We will start with the @c{setcar} function.
   Como podrías adivinar por sus nombres, las funciones @c{setcar} y
   @c{setcdr} establecen el @c{car} o el @c{cdr} de una lista a un nuevo
   valor. Ambos cambian realmente la lista original, a diferencia de @c{car} y
   @c{cdr} que dejan la lista original como estaba. Una forma de averiguar cómo
   funcionan es experimentar. Vamos a empezar con la función @c{setcar}.

#    First, we can make a list and then set the value of a variable to the
#    list, using the @c{setq} function. Here is a list of animals:
   Primero, podemos crear una lista y luego asignar el valor de una variable a
   la lista, usando la función @c{setq}. Aquí hay una lista de animales:

#    ..src > elisp
#      (setq animals '(antelope giraffe lion tiger))
#    < src..
   ..src > elisp
     (setq animales '(antilope jirafa leon tigre))
   < src..

#    If you are reading this in Info inside of GNU Emacs, you can evaluate this
#    expression in the usual fashion, by positioning the cursor after the
#    expression and typing @k{C-x C-e}.  (I'm doing this right here as I write
#    this. This is one of the advantages of having the interpreter built into
#    the computing environment. Incidentally, when there is nothing on the
#    line after the final parentheses, such as a comment, point can be on the
#    next line. Thus, if your cursor is in the first column of the next line,
#    you do not need to move it. Indeed, Emacs permits any amount of white
#    space after the final parenthesis.)
   Si estás leyendo esto dentro de GNU Emacs, puedes evaluar esta expresión de
   la forma habitual, coloca el cursor después de la expresión y presiona @k{C-x
   C-e}. (Estoy haciendo esto aqui mismo, mientras lo escribo. Esta es una de
   las ventajas de tener el intérprete construido dentro del entorno informatico.
   Por cierto, cuando no hay nada en la línea después del paréntesis final, como
   un comentario, el punto puede estar en la siguiente línea. De este modo, si
   tu cursor está en la primera columna de la siguiente línea, no es necesario
   moverlo. En realidad, Emacs permite cualquier cantidad de espacios en blanco
   después del paréntesis final.)

#    When we evaluate the variable @c{animals}, we see that it is bound to the
#    list @c{(antelope giraffe lion tiger)}:
   Cuando evaluamos la variable @c{animales}, vemos que está unida a la lista
   @c{(antilope jirafa leon tigre)}:

#    ..srci > elisp
#      > animals
#      (antelope giraffe lion tiger)
#    < srci..
   ..srci > elisp
     > animales
     (antilope jirafa leon tigre)
   < srci..

#    Put another way, the variable @c{animals} points to the list @c{(antelope
#    giraffe lion tiger)}.
   Dicho de otro modo, la variable @c{animales} apunta a la lista @c{(antilope
   jirafa leon tigre)}.

#    Next, evaluate the function @c{setcar} while passing it two arguments, the
#    variable @c{animals} and the quoted symbol @c{hippopotamus}; this is done
#    by writing the three element list @c{(setcar animals 'hippopotamus)} and
#    then evaluating it in the usual fashion:
   A continuacion, evalua la función @c{setcar} mientras le pasas dos
   argumentos, la variable @c{animales} y el símbolo citado @c{hipopotamo}; esto
   se hace escribiendo una lista de tres elementos @c{(setcar animales
   'hipopotamo)}. Evaluala de la forma habitual:

#    ..src > elisp
#      (setcar animals 'hippopotamus)
#    < src..
   ..src > elisp
     (setcar animales 'hipopotamo)
   < src..

#    After evaluating this expression, evaluate the variable @c{animals} again.
#    You will see that the list of animals has changed:
   Después de evaluar esta expresión, evalúa la variable @c{animales} de
   nuevo. Veras que la lista de animales ha cambiado:

#    ..srci > elisp
#      > animals
#      (hippopotamus giraffe lion tiger)
#    < srci..
   ..srci > elisp
     > animales
     (hipopótamo jirafa leon tigre)
   < srci..

#    The first element on the list, @c{antelope} is replaced by
#    @c{hippopotamus}.
   El primer elemento de la lista, @c{antilope} fue reemplazado por
   @c{hipopotamo}.

#    So we can see that @c{setcar} did not add a new element to the list as
#    @c{cons} would have; it replaced @c{antelope} with @c{hippopotamus}; it
#    @e{changed} the list.
   Así podemos ver que @c{setcar} no agrega un nuevo elemento a la lista como
   haria @c{cons}; Se reemplaza @c{antílope} con @c{hipopótamo}; esto @e{cambia}
   la lista.

# ** @c{setcdr}
** @c{setcdr}

#    The @c{setcdr} function is similar to the @c{setcar} function, except that
#    the function replaces the second and subsequent elements of a list rather
#    than the first element.
   La función @c{setcdr} es similar a la función @c{setcar}, excepto que la
   función reemplaza el segundo y subsiguientes elementos de una lista en lugar
   del primer elemento.

#    (To see how to change the last element of a list, look ahead to Section
#    @l{#The @c{kill-new} function}, which uses the @c{nthcdr} and @c{setcdr}
#    functions.)
   (Para ver cómo cambiar el último elemento de una lista, mira directamente en
   la Seccion @l{#La función @c{kill-new}}, que utiliza las funciones @c{nthcdr}
   y @c{setcdr}.)

#    To see how this works, set the value of the variable to a list of
#    domesticated animals by evaluating the following expression:
   Para ver cómo funciona esto, asigna el valor de la variable a una lista de
   animales domesticados evaluando la siguiente expresión:

#    ..src > elisp
#      (setq domesticated-animals '(horse cow sheep goat))
#    < src..
   ..src > elisp
     (setq animales-domesticados '(caballo vaca oveja cabra))
   < src..

#    If you now evaluate the list, you will be returned the list @c{(horse cow
#    sheep goat)}:
   Si evalúas la lista, debe devolverte la lista @c{(caballo vaca oveja cabra)}:

#    ..srci > elisp
#      > domesticated-animals
#      (horse cow sheep goat)
#    < srci..
   ..srci > elisp
     > animales-domesticados
     (caballo vaca oveja cabra)
   < srci..

#    Next, evaluate @c{setcdr} with two arguments, the name of the variable
#    which has a list as its value, and the list to which the @c{cdr} of the
#    first list will be set;
   Luego, evalúa @c{setcdr} con dos argumentos, el nombre de la variable que
   tiene una lista como su valor, y la lista a la que se establecera el @c{cdr}
   de la primera lista;

#    ..src > elisp
#      (setcdr domesticated-animals '(cat dog))
#    < src..
   ..src > elisp
     (setcdr animales-domesticados '(gato perro))
   < src..

#    If you evaluate this expression, the list @c{(cat dog)} will appear in the
#    echo area. This is the value returned by the function. The result we are
#    interested in is the “side effect”, which we can see by evaluating the
#    variable @c{domesticated-animals}:
   Si evalúas esta expresión, la lista @c{(gato perro)} aparecerá en el área
   echo. Este es el valor devuelto por la función. El resultado que nos interesa
   es el “efecto secundario”, que podemos ver evaluando la variable
   @c{animales-domesticados}:

#    ..srci > elisp
#      > domesticated-animals
#      (horse cat dog)
#    < srci..
   ..srci > elisp
     > animales-domesticados
     (caballo gato perro)
   < srci..

#    Indeed, the list is changed from @c{(horse cow sheep goat)} to @c{(horse
#    cat dog)}. The @c{cdr} of the list is changed from @c{(cow sheep goat)}
#    to @c{(cat dog)}.
   En efecto, la lista cambia de @c{(caballo vaca oveja cabra)} a @c{(caballo
   gato perro)}. El @c{cdr} de la lista cambia de @c{(vaca oveja cabra)} a
   @c{(gato perro)}.

# ** Exercise
** Ejercicio

#    Construct a list of four birds by evaluating several expressions with
#    @c{cons}. Find out what happens when you @c{cons} a list onto itself.
#    Replace the first element of the list of four birds with a fish. Replace
#    the rest of that list with a list of other fish.
   Construye una lista de cuatro pájaros evaluando varias expresiones con
   @c{cons}. Descubre que ocurre cuando aplicas @c{cons} a una lista sobre si
   misma. Reemplaza el primer elemento de la lista de cuatro pájaros con un
   pez. Reemplaza el resto de esta lista con una lista de otros peces.

# * Cutting and Storing Text
* Cortar y Almacenar Texto

#   Whenever you cut or clip text out of a buffer with a ‘kill’ command in GNU
#   Emacs, it is stored in a list and you can bring it back with a ‘yank’
#   command.
  Cada vez que se corta texto de un búfer con un comando ‘kill’, se almacena
  en una lista y puedes traerlo de vuelta con un comando ‘yank’.

#   (The use of the word ‘kill’ in Emacs for processes which specifically @e{do
#   not} destroy the values of the entities is an unfortunate historical
#   accident. A much more appropriate word would be ‘clip’ since that is what
#   the kill commands do; they clip text out of a buffer and put it into
#   storage from which it can be brought back. I have often been tempted to
#   replace globally all occurrences of ‘kill’ in the Emacs sources with ‘clip’
#   and all occurrences of ‘killed’ with ‘clipped’.)
  (El uso de la palabra ‘kill’ @%i(matar) en Emacs para procesos que
  específicamente @e{no} destruyen los valores de las entidades es un accidente
  histórico desafortunado. Una palabra mucho más apropiada seria ‘clip’
  @%i(recortar) ya que eso es lo que hacen los comandos @'(kill); recortan el
  texto de un búfer y lo almacenan para que puede traerse de vuelta. Con
  frecuencia me he sentido tentado a sustituir globalmente todas las apariciones
  de ‘kill’ en el codigo de Emacs con ‘clip’ y todas las apariciones de ‘killed’
  @%i(destruido) con ‘clipped’ @%i(cortado).)

#   When text is cut out of a buffer, it is stored on a list. Successive
#   pieces of text are stored on the list successively, so the list might look
#   like this:
  Cuando el texto se corta de un búfer, se almacena en una lista. Los fragmentos de
  texto se almacenan en la lista de forma sucesiva, por lo que la lista podría verse
  así:

#   ..src > elisp
#     ("a piece of text" "previous piece")
#   < src..
  ..src > elisp
    ("una pieza de texto" "pieza anterior")
  < src..

#   The function @c{cons} can be used to create a new list from a piece of text
#   (an ‘atom’, to use the jargon) and an existing list, like this:
  La función @c{cons} se puede utilizar para crear una nueva lista a partir de
  un trozo de texto (un ‘átomo’, para usar la jerga) y una lista existente,
  como esta:

#   ..src > elisp
#     (cons "another piece"
#           '("a piece of text" "previous piece"))
#   < src..
  ..src > elisp
    (cons "otra pieza"
          '("una pieza de texto" "pieza anterior"))
  < src..

#   If you evaluate this expression, a list of three elements will appear in
#   the echo area:
  Si evaluas esta expresión, aparecera una lista de tres elementos en el área
  de eco:

#   ..src > elisp
#     ("another piece" "a piece of text" "previous piece")
#   < src..
  ..src > elisp
    ("otra pieza" "una pieza de texto" "pieza anterior")
  < src..

#   With the @c{car} and @c{nthcdr} functions, you can retrieve whichever piece
#   of text you want. For example, in the following code, @c{nthcdr 1 …}
#   returns the list with the first item removed; and the @c{car} returns the
#   first element of that remainder––the second element of the original list:
  Puedes recuperar cualquier pieza de texto que desees, con las funciones
  @c{car} y @c{nthcdr}. Por ejemplo, en el siguiente código, @c(nthcdr 1 …)
  devuelve la lista con el primer elemento eliminado; y @c{car} devuelve el
  primer elemento de ese resto––el segundo elemento de la lista original:

#   ..srci > elisp
#     > (car (nthcdr 1 '("another piece"
#     ^                  "a piece of text"
#     ^                  "previous piece")))
#     "a piece of text"
#   < srci..
  ..srci > elisp
    > (car (nthcdr 1 '("otra pieza"
    ^                  "una pieza de texto"
    ^                  "pieza anterior")))
    "una pieza de texto"
  < srci..

#   The actual functions in Emacs are more complex than this, of course. The
#   code for cutting and retrieving text has to be written so that Emacs can
#   figure out which element in the list you want––the first, second, third, or
#   whatever. In addition, when you get to the end of the list, Emacs should
#   give you the first element of the list, rather than nothing at all.
  Por supuesto, las funciones reales en Emacs son más complejas que esto. El
  código para el corte y recuperarcion de texto tiene que ser escrito de modo
  que Emacs pueda determinar qué elemento en la lista se quiere––el primero,
  segundo, tercero o cualquier otro. Además, cuando se llega al final de la
  lista, Emacs deberia darte el primer elemento de la lista, en lugar de nada en
  absoluto.

#   The list that holds the pieces of text is called the @:{kill ring}. This
#   chapter leads up to a description of the kill ring and how it is used by
#   first tracing how the @c{zap-to-char} function works. This function uses
#   (or ‘calls’) a function that invokes a function that manipulates the kill
#   ring. Thus, before reaching the mountains, we climb the foothills.
  La lista que contiene los trozos de texto se llama @:(kill ring) @%i(anillo de
  la muerte). En este capítulo se hace una descripción del anillo de la muerte y
  como se utiliza en un primer vistazo a la función @c{zap-to-char}. Esta
  función utiliza (o ‘llama’) a una función que invoca a otra función que
  manipula el anillo de la muerte. Por la tanto, antes de llegar a las montañas,
  debemos escalar las colinas.

#   A subsequent chapter describes how text that is cut from the buffer is
#   retrieved. See Section @l{#Yanking Text Back}.
  En un capítulo posterior se describe cómo se recupera el texto que se corta de
  un buffer. Consulta la Sección @l{#Traer de regreso el texto}.

# ** @c{zap-to-char}
** @c{zap-to-char}

#    The @c{zap-to-char} function changed little between GNU Emacs version 19
#    and GNU Emacs version 22. However, @c{zap-to-char} calls another
#    function, @c{kill-region}, which enjoyed a major rewrite.
   La función @c{zap-to-char} apenas ha variado entre la versión 19 y 22 de GNU
   Emacs. Sin embargo, @c{zap-to-char} llama a otra función, @c{kill-region},
   que ha tenido una importante reescritura.

#    The @c{kill-region} function in Emacs 19 is complex, but does not use code
#    that is important at this time. We will skip it.
   La función @c{kill-region} en Emacs 19 es compleja, pero no utiliza código
   que sea importante en este momento. Nos Lo saltaremos.

#    The @c{kill-region} function in Emacs 22 is easier to read than the same
#    function in Emacs 19 and introduces a very important concept, that of
#    error handling. We will walk through the function.
   La función @c{kill-region} en Emacs 22 es más fácil de leer que la misma
   función en Emacs 19 e introduce un concepto muy importante, la gestion de
   errores. Caminaremos a través de la función.

#    But first, let us look at the interactive @c{zap-to-char} function.
   Pero primero, veamos la función interactiva @c{zap-to-char}.

#    The @c{zap-to-char} function removes the text in the region between the
#    location of the cursor (i.e., of point) up to and including the next
#    occurrence of a specified character. The text that @c{zap-to-char}
#    removes is put in the kill ring; and it can be retrieved from the kill
#    ring by typing @k{C-y} @%c(yank). If the command is given an argument,
#    it removes text through that number of occurrences. Thus, if the cursor
#    were at the beginning of this sentence and the character were @'{s},
#    @'{Thus} would be removed. If the argument were two, @'{Thus, if the
#    curs} would be removed, up to and including the @'{s} in @'{cursor}.
   La función @c{zap-to-char} elimina el texto en la región entre la ubicacion
   del cursor (es decir, del punto) hasta e incluyendo la siguiente aparicion de
   un caracter específicado. El texto que @c{zap-to-char} elimina se pone en el
   anillo de la muerte; y se puede recuperar escribiendo @k{C-y} @%c(yank). Si
   el comando recive un argumento, elimina el texto a través de ese número de
   ocurrencias. Por lo tanto, si el cursor estuviera al inicio de esta frase y
   el carácter fuera @'{s}, se eliminaria @'{Por lo tanto, s}. Si el argumento
   fuera dos, se eliminaria @'{Por lo tanto, si el curs}, hasta e incluiendo la
   @'{s} en @'{cursor}.

#    If the specified character is not found, @c{zap-to-char} will say “Search
#    failed”, tell you the character you typed, and not remove any text.
   Si no se encuentra el carácter específicado @c{zap-to-char} dirá “Search
   failed” @%i(Búsqueda fallida), te indicaria el caracter que escribiste, y no
   eliminara ningun texto.

#    In order to determine how much text to remove, @c{zap-to-char} uses a
#    search function. Searches are used extensively in code that manipulates
#    text, and we will focus attention on them as well as on the deletion
#    command.
   Para determinar la cantidad de texto a eliminar @c{zap-to-char} utiliza una
   función de búsqueda. Las búsquedas se utilizan ampliamente en código que
   manipula el texto, y vamos a centrar la atención en ellos, asi como en el
   comando de eliminacion.

#    Here is the complete text of the version 22 implementation of the
#    function:
   Aquí está el texto completo de la función en la versión 22:

#    ..src > elisp
#      (defun zap-to-char (arg char)
#        "Kill up to and including ARG'th occurrence of CHAR.
#      Case is ignored if ‘case-fold-search’ is non-nil in the current buffer.
#      Goes backward if ARG is negative; error if CHAR not found."
#        (interactive "p\ncZap to char: ")
#        (if (char-table-p translation-table-for-input)
#            (setq char (or (aref translation-table-for-input char) char)))
#        (kill-region (point) (progn
#                               (search-forward (char-to-string char) nil nil arg)
#                               (point))))
#    < src..
   ..src > elisp
     (defun zap-to-char (arg char)
       "Corta e incluye la aparicion de la enesima ocurrencia (ARG) del caracter CHAR.
     Se ignora entre mayusculas y minusculas si ‘case-fold-search’ es no-nil en
     el buffer actual.
     Retrocede si ARG es negativo; error si CHAR no se encuentra."
       (interactive "p\ncZap to char: ")
       (if (char-table-p translation-table-for-input)
           (setq char (or (aref translation-table-for-input char) char)))
       (kill-region (point) (progn
                              (search-forward (char-to-string char) nil nil arg)
                              (point))))
   < src..

#    The documentation is thorough. You do need to know the jargon meaning of
#    the word ‘kill’.
   La linea de documentacion esta traducida al español. En la version original
   no se utiliza la palabra ‘Corta’ en su lugar se utiliza ‘kill’.

# *** The @c{interactive} Expression
*** La expresión @c{interactive}

#     The interactive expression in the @c{zap-to-char} command looks like
#     this:
    La expresión interactiva en el comando @c{zap-to-char} es esta:

#     ..src > elisp
#       (interactive "p\ncZap to char: ")
#     < src..
    ..src > elisp
      (interactive "p\ncZap to char: ")
    < src..

#     The part within quotation marks, @c{"p\ncZap to char: "}, specifies two
#     different things. First, and most simply, is the @'c{p}. This part is
#     separated from the next part by a newline, @'c{\n}. The @'c{p} means that
#     the first argument to the function will be passed the value of a
#     ‘processed prefix’. The prefix argument is passed by typing @k{C-u} and
#     a number, or @k{M-} and a number. If the function is called
#     interactively without a prefix, 1 is passed to this argument.
    La parte entre comillas, @c{"p\ncZap to char: "}, especifica dos cosas
    diferentes. Primero, y lo mas sencillo, es la @'c{p}. Esta parte se separa de
    la siguiente parte por una línea nueva, @'c{\n}. La @'c{p} significa que a el
    primer argumento de la función será pasando el valor de un ‘prefijo
    procesado’. El argumento prefijo se pasa escribiendo @k{C-u} y un número, o
    @k{M-} y un número. Si la función se llamada interactivamente sin un
    prefijo, se pasa 1 a este argumento.

#     The second part of @c{"p\ncZap to char: "} is @'c{cZap to char: }. In
#     this part, the lower case @'c{c} indicates that @c{interactive} expects a
#     prompt and that the argument will be a character. The prompt follows the
#     @'c{c} and is the string @'c{Zap to char: } (with a space after the colon
#     to make it look good).
    La segunda parte de @c{"p\ncZap to char: "} es @'c{cZap to char:}. En esta
    parte, la @'c{c} minuscula indica que @c{interactive} espera un prompt y que
    el argumento será un caracter. El prompt va despues de @'c{c} y es la cadena
    @'c{Zap to char: } (con un espacio después de los dos puntos para que se vea bien).

#     What all this does is prepare the arguments to @c{zap-to-char} so they
#     are of the right type, and give the user a prompt.
    Lo que todo esto hace es preparar los argumentos de @c{zap-to-char} para que
    sean del tipo correcto, y darle al usuario un prompt.

#     In a read-only buffer, the @c{zap-to-char} function copies the text to
#     the kill ring, but does not remove it. The echo area displays a message
#     saying that the buffer is read-only. Also, the terminal may beep or
#     blink at you.
    En un búfer de solo lectura, la función @c{zap-to-char} copia el texto al
    anillo de la muerte, pero no lo elimina. El área de eco muestra un mensaje
    diciendo que el búfer es de solo lectura. Ademas, el terminal puede emitir
    un pitido o parpadear.

# *** The Body of @c{zap-to-char}
*** El cuerpo de @c{zap-to-char}

#     The body of the @c{zap-to-char} function contains the code that kills
#     (that is, removes) the text in the region from the current position of
#     the cursor up to and including the specified character.
    El cuerpo de la función @c{zap-to-char} contiene el código que mata (es
    decir, elimina) el texto en la región desde la posición actual del cursor
    hasta e incluyendo el carácter especificado.

#     The first part of the code looks like this:
    La primera parte del código luce asi:

#     ..src > elisp
#       (if (char-table-p translation-table-for-input)
#           (setq char (or (aref translation-table-for-input char) char)))
#       (kill-region (point) (progn
#                              (search-forward (char-to-string char) nil nil arg)
#                              (point)))
#     < src..
    ..src > elisp
      (if (char-table-p translation-table-for-input)
          (setq char (or (aref translation-table-for-input char) char)))
      (kill-region (point) (progn
                             (search-forward (char-to-string char) nil nil arg)
                             (point)))
    < src..

#     @c{char-table-p} is an hitherto unseen function. It determines whether
#     its argument is a character table. When it is, it sets the character
#     passed to @c{zap-to-char} to one of them, if that character exists, or to
#     the character itself.  (This becomes important for certain characters in
#     non-European languages. The @c{aref} function extracts an element from
#     an array. It is an array-specific function that is not described in this
#     document. See Section @l{elisp.html#Arrays<>Arrays} in @e{The GNU Emacs
#     Lisp Reference Manual}.)
    @c{char-table-p} es una función que aun no hemos visto. Determina si su argumento
    es una tabla de caracteres. Si lo es, establece el caracter pasado a
    @c{zap-to-char} a uno de ellos, si ese carácter existe, o al carácter en
    sí. (Esto es importante para ciertos caracteres en idiomas no europeos. La
    función @c{aref} extrae un elemento desde un arreglo. Esta funcion es
    específica para arreglos y no sera descrita en este documento. Consulta la Seccion
    @l{elisp.html#Arrays<>Arreglos} en @e(El Manual de Referencia de GNU Emacs
    Lisp).)

#     @c{(point)} is the current position of the cursor.
    @c{(point)} es la posición actual del cursor.

#     The next part of the code is an expression using @c{progn}. The body of
#     the @c{progn} consists of calls to @c{search-forward} and @c{point}.
    La siguiente parte del código es una expresión utilizando @c{progn}. El
    cuerpo de @c{progn} consiste en llamadas a @c{search-forward} y @c{point}.

#     It is easier to understand how @c{progn} works after learning about
#     @c{search-forward}, so we will look at @c{search-forward} and then at
#     @c{progn}.
    Es fácil comprender cómo funciona @c{progn} después de aprender sobre
    @c{search-forward}, asi que veremos @c{search-forward} y luego @c{progn}.

# *** The @c{search-forward} Function
*** La Función @c{search-forward}

#     The @c{search-forward} function is used to locate the
#     zapped-for-character in @c{zap-to-char}. If the search is successful,
#     @c{search-forward} leaves point immediately after the last character in
#     the target string.  (In @c{zap-to-char}, the target string is just one
#     character long.  @c{zap-to-char} uses the function @c{char-to-string} to
#     ensure that the computer treats that character as a string.)  If the
#     search is backwards, @c{search-forward} leaves point just before the
#     first character in the target. Also, @c{search-forward} returns @c{t}
#     for true.  (Moving point is therefore a ‘side effect’.)
    La función @c{search-forward} se utiliza para localizar el caracter a borrar
    en @c{zap-to-char}. Si la búsqueda es exitosa, @c{search-forward} deja el
    punto inmediatamente después del último carácter en la cadena objetivo. (En
    @c{zap-to-char}, la cadena objetivo tiene solo un carácter longitud.
    @c{zap-to-char} usa la función @c{char-to-string} para asegurar que el
    computador trata este carácter como una cadena). Si la búsqueda es hacia
    atrás, @c{search-forward} deja el punto justo antes del primer carácter en
    el objetivo. Ademas, @c{search-forward} devuelve @c{t} para verdadero. (Por
    lo tanto, desplazar el punto es un ‘efecto secundario’.)

#     In @c{zap-to-char}, the @c{search-forward} function looks like this:
    En @c{zap-to-char}, la función @c{search-forward} se ve así:

#     ..src > elisp
#       (search-forward (char-to-string char) nil nil arg)
#     < src..
    ..src > elisp
      (search-forward (char-to-string char) nil nil arg)
    < src..

#     The @c{search-forward} function takes four arguments:
    La función @c{search-forward} utiliza cuatro argumentos:

#     1. The first argument is the target, what is searched for. This must be
#        a string, such as @c{"z"}.
    1. El primer argumento es el objetivo, que esta buscando. Debe ser una
       cadena, como @c{"z"}.

#        As it happens, the argument passed to @c{zap-to-char} is a single
#        character. Because of the way computers are built, the Lisp
#        interpreter may treat a single character as being different from a
#        string of characters. Inside the computer, a single character has a
#        different electronic format than a string of one character.  (A single
#        character can often be recorded in the computer using exactly one
#        byte; but a string may be longer, and the computer needs to be ready
#        for this.)  Since the @c{search-forward} function searches for a
#        string, the character that the @c{zap-to-char} function receives as
#        its argument must be converted inside the computer from one format to
#        the other; otherwise the @c{search-forward} function will fail. The
#        @c{char-to-string} function is used to make this conversion.
       Sucede que el argumento pasado a @c{zap-to-char} es un solo
       caracter. Debido a la forma en la que se construyen los computadores, el
       intérprete Lisp puede tratar un solo caracter de forma distinta a una
       cadena de caracteres. Dentro del computador, un solo caracter tiene un
       formato electrónico diferente a una cadena de un caracteres. (Un solo
       caracter con frecuencia puede grabarse en el computador utilizardo
       exactamente un byte; pero una cadena puede ser mas larga, y el equipo
       debe estar listo para ello.) Ya que la función @c{search-forward} busca
       una cadena, el caracter que recive la función @c{zap-to-char} como
       argumento debe convertirse dentro del computador de un formato a otro; de
       lo contrario, la función @c{search-forward} fallará. Se utiliza la
       función @c{char-to-string} para realizar esta conversión.

#     2. The second argument bounds the search; it is specified as a position
#        in the buffer. In this case, the search can go to the end of the
#        buffer, so no bound is set and the second argument is @c{nil}.
    2. El segundo argumento limita la búsqueda; se especifica como una posición
       en el búfer. En este caso, la búsqueda puede ir al final del búfer, por
       lo que no se establece ningun limite y el segundo argumento es @c{nil}.

#     3. The third argument tells the function what it should do if the search
#        fails––it can signal an error (and print a message) or it can return
#        @c{nil}. A @c{nil} as the third argument causes the function to
#        signal an error when the search fails.
    3. El tercer argumento le dice a la función lo que debe hacer si la búsqueda
       falla––puede señalar un error (e imprimir un mensaje) o puede devolver
       @c{nil}. Un @c{nil} como el tercer argumento hace que la función señale
       un error cuando la búsqueda falla.

#     4. The fourth argument to @c{search-forward} is the repeat count––how
#        many occurrences of the string to look for. This argument is optional
#        and if the function is called without a repeat count, this argument is
#        passed the value 1. If this argument is negative, the search goes
#        backwards.
    4. El cuarto argumento de @c{search-forward} es el contador de
       repeticion––cuántas ocurrencias de la cadena hay que buscar. Este
       argumento es opcional y si la función se llamada sin contador de
       repeticion, este argumento pasa el valor 1. Si este argumento es
       negativo, la búsqueda va hacia atrás.


#     In template form, a @c{search-forward} expression looks like this:
    En formato plantilla, una expresión @c{search-forward} tiene este aspecto:

#     ..src > elisp
#       (search-forward "target-string"
#                       limit-of-search
#                       what-to-do-if-search-fails
#                       repeat-count)
#     < src..
    ..src > elisp
      (search-forward "cadena-a-buscar"
                      limite-de-busqueda
                      que-hacer-si-la-busqueda-falla
                      contador-de-repeticion)
    < src..

#     We will look at @c{progn} next.
    A continuacion veremos @c{progn}.

# *** The @c{progn} Special Form
*** La forma especial @c{progn}

#     @c{progn} is a special form that causes each of its arguments to be
#     evaluated in sequence and then returns the value of the last one. The
#     preceding expressions are evaluated only for the side effects they
#     perform. The values produced by them are discarded.
    @c{progn} es una forma especial que hace que cada uno de sus argumentos sea
    evaluado en secuencia y luego devuelve el valor del último. Las expresiones
    anteriores solo se evaluan por los efectos secundarios que producen. Los
    valores producidos son descartados.

#     The template for a @c{progn} expression is very simple:
    La plantilla de una expresión @c{progn} es muy simple:

#     ..src > elisp
#       (progn
#         body…)
#     < src..
    ..src > elisp
      (progn
        cuerpo…)
    < src..

#     In @c{zap-to-char}, the @c{progn} expression has to do two things: put
#     point in exactly the right position; and return the location of point so
#     that @c{kill-region} will know how far to kill to.
    En @c{zap-to-char}, la expresión @c{progn} tiene que hacer dos cosas: poner
    el punto exactamente en la posición correcta; y devolver la posición del
    punto para que @c{kill-region} sepa hasta donde cortar.

#     The first argument to the @c{progn} is @c{search-forward}. When
#     @c{search-forward} finds the string, the function leaves point
#     immediately after the last character in the target string.  (In this case
#     the target string is just one character long.)  If the search is
#     backwards, @c{search-forward} leaves point just before the first
#     character in the target. The movement of point is a side effect.
    El primer argumento de @c{progn} es @c{search-forward}. Cuando
    @c{search-forward} encuentra la cadena, la función deja el punto
    inmediatamente después del último caracter en la cadena objetivo. (En este
    caso la cadena objetivo tiene solo un carácter de longitud.) Si la búsqueda es
    hacia atrás, @c{search-forward} deja el punto justo antes del primer
    carácter objetivo. El movimiento del punto es un efecto secundario.

#     The second and last argument to @c{progn} is the expression @c{(point)}.
#     This expression returns the value of point, which in this case will be
#     the location to which it has been moved by @c{search-forward}.  (In the
#     source, a line that tells the function to go to the previous character,
#     if it is going forward, was commented out in 1999; I don't remember
#     whether that feature or mis-feature was ever a part of the distributed
#     source.)  The value of @c{point} is returned by the @c{progn} expression
#     and is passed to @c{kill-region} as @c{kill-region}'s second argument.
    El segundo y último argumento de @c{progn} es la expresión @c{(point)}. Esta
    expresión devuelve el valor del punto, que en este caso será la ubicacion a
    la que se ha desplazado por @c{search-forward}. (En el codigo, una línea le
    indicaba a la función que debia ir un carácter atras, si va hacia adelante, se
    comentó en 1999; yo no recuerdo si esta caracteriscita o funcion incorrecta
    alguna vez fue parte del codigo distribuido.) El valor de @c{point} es
    devuelto por la expresión @c{progn} y se pasa a @c{kill-region} como el
    segundo argumento de @c{kill-region} .

# *** Summing up @c{zap-to-char}
*** Resumiendo @c{zap-to-char}

#     Now that we have seen how @c{search-forward} and @c{progn} work, we can
#     see how the @c{zap-to-char} function works as a whole.
    Ahora que hemos visto cómo funcionan @c{search-forward} y @c{progn}, podemos
    ver cómo la función @c{zap-to-como} trabaja como un todo.

#     The first argument to @c{kill-region} is the position of the cursor when
#     the @c{zap-to-char} command is given––the value of point at that time.
#     Within the @c{progn}, the search function then moves point to just after
#     the zapped-to-character and @c{point} returns the value of this location.
#     The @c{kill-region} function puts together these two values of point, the
#     first one as the beginning of the region and the second one as the end of
#     the region, and removes the region.
    El primer argumento de @c{kill-region} es la posición del cursor cuando se
    da el comando @c{zap-to-char}––el valor de punto en ese momento. Dentro de
    @c{progn}, la funcion de búsqueda mueve el punto justo después del caracter
    a borrar y @c{point} devuelve el valor de esa ubicacion. La función
    @c{kill-region} reune estos dos valores de punto, el primero como el inicio
    de la región y el segundo como el final de la región, y elimina la región.

#     The @c{progn} special form is necessary because the @c{kill-region}
#     command takes two arguments; and it would fail if @c{search-forward} and
#     @c{point} expressions were written in sequence as two additional
#     arguments. The @c{progn} expression is a single argument to
#     @c{kill-region} and returns the one value that @c{kill-region} needs for
#     its second argument.
    La forma especial @c{progn} es necesaria porque el comando @c{kill-region}
    toma dos argumentos; y fallaría si las expresiones @c{search-forward} y
    @c{point} se escribieran en secuencia como dos argumentos adicionales. La
    expresión @c{progn} es solo un argumento para @c{kill-region} y devuelve el
    valor que @c{kill-region} necesita para su segundo argumento.

# ** @c{kill-region}
** @c{kill-region}

#    The @c{zap-to-char} function uses the @c{kill-region} function. This
#    function clips text from a region and copies that text to the kill ring,
#    from which it may be retrieved.
   La función @c{zap-to-char} utiliza la función @c{kill-region}. Esta función
   corta texto de una región y copia ese texto al anillo de la muerte, desde el
   que puede ser recuperado.

#    The Emacs 22 version of that function uses @c{condition-case} and
#    @c{copy-region-as-kill}, both of which we will explain.
#    @c{condition-case} is an important special form.
   La versión en Emacs 22 de esta funcion utiliza @c{condition-case} y
   @c{copy-region-as-kill}, ambas seran explicadas. @c{condition-case} es una
   forma especial importante.

#    In essence, the @c{kill-region} function calls @c{condition-case}, which
#    takes three arguments. In this function, the first argument does nothing.
#    The second argument contains the code that does the work when all goes
#    well. The third argument contains the code that is called in the event of
#    an error.
   En esencia, la función @c{kill-region} llama a @c{condition-case}, que toma
   tres argumentos. En esta función, el primer argumento no hace nada. El
   segundo argumento contiene el código que hace el trabajo cuando todo va
   bien. El tercer argumento contiene el código que se llama en caso de error.

#    We will go through the @c{condition-case} code in a moment. First, let us
#    look at the definition of @c{kill-region}, with comments added:
   Revisaremos el código de @c{condition-case} en un momento. Primero, veamos la
   definición de @c{kill-region}, con comentarios añadidos:

#    ..src > elisp
   ..src > elisp
#      (defun kill-region (beg end)
     (defun kill-region (beg end)
#        "Kill (\"cut\") text between point and mark.
#      This deletes the text from the buffer and saves it in the kill ring.
#      The command \\[yank] can retrieve it from there. … "
       "Kill (\"corta\") el texto entre el punto y la marca.
     Esto elimina el texto del buffer y lo guarda en el anillo de la muerte.
     El comando \\[yank] puede recuperarlo desde alli. … "

#        ;; • Since order matters, pass point first.
       ;; • Puesto que el orden importa, primero pasa el punto.
#        (interactive (list (point) (mark)))
       (interactive (list (point) (mark)))
#        ;; • And tell us if we cannot cut the text.
#        ;; ‘unless’ is an ‘if’ without a then-part.
       ;; • Y dinos si no podemos cortar el texto.
       ;; ‘unless’ es un ‘if’ sin parte-then.
#        (unless (and beg end)
#          (error "The mark is not set now, so there is no region"))
       (unless (and beg end)
         (error "La marca no esta definida, asi que no hay ninguna region"))
#        ;; • ‘condition-case’ takes three arguments.
#        ;;    If the first argument is nil, as it is here,
#        ;;    information about the error signal is not
#        ;;    stored for use by another function.
       ;; • ‘condition-case’ toma tres argumentos.
       ;;    Si el primer argumento es nil, como aqui,
       ;;    la informacion del error no se almacena
       ;;    para ser utilizado por otra funcion.
#        (condition-case nil
       (condition-case nil

#            ;; • The second argument to ‘condition-case’ tells the
#            ;;    Lisp interpreter what to do when all goes well.
           ;; • El segundo argumento de ‘condition-case’ le dice al
           ;;    interprete Lisp que hacer cuando todo va bien.

#            ;;    It starts with a ‘let’ function that extracts the string
#            ;;    and tests whether it exists. If so (that is what the
#            ;;    ‘when’ checks), it calls an ‘if’ function that determines
#            ;;    whether the previous command was another call to
#            ;;    ‘kill-region’; if it was, then the new text is appended to
#            ;;    the previous text; if not, then a different function,
#            ;;    ‘kill-new’, is called.
           ;;    Empieza con una funcion ‘let’ que extrae la cadena y
           ;;    comprueba si existe. Si es asi (eso es lo que comprueba
           ;;    ‘when’), esta llama a una funcion ‘if’ que determina
           ;;    si el comando anterior fue otra llamada a ‘kill-region’;
           ;;    si lo fue, el nuevo texto se añade al texto anterior; si
           ;;    no, se llama a una funcion diferente, se llama a ‘kill-new’.

#            ;;    The ‘kill-append’ function concatenates the new string and
#            ;;    the old. The ‘kill-new’ function inserts text into a new
#            ;;    item in the kill ring.
           ;;    La funcion ‘kill-append’ concatena la cadena nueva y antigua.
           ;;    La funcion ‘kill-new’ inserta el texto dentro de un nuevo
           ;;    elemento en el anillo de la muerte.

#            ;;    ‘when’ is an ‘if’ without an else-part. The second ‘when’
#            ;;    again checks whether the current string exists; in
#            ;;    addition, it checks whether the previous command was
#            ;;    another call to ‘kill-region’. If one or the other
#            ;;    condition is true, then it sets the current command to
#            ;;    be ‘kill-region’.
           ;;    ‘when’ es un ‘if’ sin una parte-else. El segundo ‘when’
           ;;    comprueba de nuevo si la cadena actual existe; Ademas,
           ;;    comprueba si el comando anterior fue otra llamada a
           ;;    ‘kill-region’. Si una u otra condicion es verdadera,
           ;;    entonces establece que el comando actual sea ‘kill-region’.
#            (let ((string (filter-buffer-substring beg end t)))
#              (when string                    ;STRING is nil if BEG = END
           (let ((string (filter-buffer-substring beg end t)))
             (when string                    ;STRING es nil si BEG = END
#                ;; Add that string to the kill ring, one way or another.
               ;; agrega esa cadena al anillo de la muerte, de uno forma u otra.
#                (if (eq last-command 'kill-region)
               (if (eq last-command 'kill-region)
#                    ;;    − ‘yank-handler’ is an optional argument to
#                    ;;    ‘kill-region’ that tells the ‘kill-append’ and
#                    ;;    ‘kill-new’ functions how deal with properties
#                    ;;    added to the text, such as ‘bold’ or ‘italics’.
                   ;;    − ‘yank-handler’ es un argumento opcional de
                   ;;    ‘kill-region’ que indica a las funciones ‘kill-append’
                   ;;    y ‘kill-new’ como tratar las propiedades añadidas al
                   ;;    texto, como ‘negrita’ o ‘cursiva’.
#                    (kill-append string (< end beg) yank-handler)
#                  (kill-new string nil yank-handler)))
#              (when (or string (eq last-command 'kill-region))
#                (setq this-command 'kill-region))
#              nil)
                   (kill-append string (< end beg) yank-handler)
                 (kill-new string nil yank-handler)))
             (when (or string (eq last-command 'kill-region))
               (setq this-command 'kill-region))
             nil)

#          ;;  • The third argument to ‘condition-case’ tells the interpreter
#          ;;    what to do with an error.
#          ;;    The third argument has a conditions part and a body part.
#          ;;    If the conditions are met (in this case,
#          ;;             if text or buffer are read-only)
#          ;;    then the body is executed.
#          ;;    The first part of the third argument is the following:
         ;;  • El tercer argumento de ‘condition-case’ le dice al interprete
         ;;    que hacer con un error.
         ;;    El tercer argumento tiene una parte de condiciones y una parte cuerpo.
         ;;    Si se cumplen las condiciones (en este caso,
         ;;             si el texto o el buffer son de solo lectura)
         ;;    entonces se ejecuta el cuerpo.
         ;;    La primer parte del tercer argumento es la siguiente:
#          ((buffer-read-only text-read-only) ;; the if-part
         ((buffer-read-only text-read-only) ;; la parte-if
#           ;; …  the then-part
          ;; …  la parte-then
#           (copy-region-as-kill beg end)
          (copy-region-as-kill beg end)
#           ;;    Next, also as part of the then-part, set this-command, so
#           ;;    it will be set in an error
          ;;    A continuacion, tambien como parte de la parte-then, establece
          ;;    this-command, por lo que se establece en un error
#           (setq this-command 'kill-region)
          (setq this-command 'kill-region)
#           ;;    Finally, in the then-part, send a message if you may copy
#           ;;    the text to the kill ring without signaling an error, but
#           ;;    don't if you may not.
          ;;    Finalmente, en la pante-then, envia un mensaje si puede copiar
          ;;    el texto en el anillo de la muerte sin señalar un error, pero
          ;;    no lo hace si no puede.
#           (if kill-read-only-ok
#               (progn (message "Read only text copied to kill ring") nil)
#             (barf-if-buffer-read-only)
          (if kill-read-only-ok
              (progn (message "Read only text copied to kill ring") nil)
            (barf-if-buffer-read-only)
#             ;; If the buffer isn't read-only, the text is.
            ;; Si el buffer no es de solo lectura, el texto lo es.
#             (signal 'text-read-only (list (current-buffer)))))
            (signal 'text-read-only (list (current-buffer)))))
#    < src..
   < src..

# *** @c{condition-case}
*** @c{condition-case}

#     As we have seen earlier (see Section @l{#Generate an Error Message}), when
#     the Emacs Lisp interpreter has trouble evaluating an expression, it
#     provides you with help; in the jargon, this is called “signaling an
#     error”. Usually, the computer stops the program and shows you a message.
    Como se ha visto antes (Consulta la Seccion @l{#Generar un Mensaje de Error}), cuando
    el intérprete de Emacs Lisp tiene problemas evaluando una expresión, te
    proporciona ayuda; en la jerga, esto se llama “Señalar un error”.
    Normalmente, el computador detiene el programa y te muestra un mensaje.

#     However, some programs undertake complicated actions. They should not
#     simply stop on an error. In the @c{kill-region} function, the most
#     likely error is that you will try to kill text that is read-only and
#     cannot be removed. So the @c{kill-region} function contains code to
#     handle this circumstance. This code, which makes up the body of the
#     @c{kill-region} function, is inside of a @c{condition-case} special form.
    Sin embargo, algunos programas emprenden acciones complicadas. No deberian
    simplemente detenerse en un error. En la función @c{kill-region}, el error
    mas probable es que intente cortar texto que sea de solo lectura y no pueda
    ser eliminado. Así que la función @c{kill-region} contiene código para
    manejar esta circunstancia. Este código, que forma el cuerpo de la función
    @c{kill-region}, se encuentra dentro de una forma especial @c{condition-case}.

#     The template for @c{condition-case} looks like this:
    La plantilla para @c{condition-case} tiene este aspecto:

#     ..src > elisp
#       (condition-case
#         var
#         bodyform
#         error-handler…)
#     < src..
    ..src > elisp
      (condition-case
        var
        bodyform
        gestor-de-errores…)
    < src..

#     The second argument, @c{bodyform}, is straightforward. The
#     @c{condition-case} special form causes the Lisp interpreter to evaluate
#     the code in @c{bodyform}. If no error occurs, the special form returns
#     the code's value and produces the side-effects, if any.
    El segundo argumento, @c{bodyform} es sencillo. La forma especial
    @c{condition-case} hace que el intérprete Lisp evalúe el código en
    @c{bodyform}. Si no ocurre ningún error, la forma especial devuelve el valor
    del código y produce los efectos secundarios, si los hubiera.

#     In short, the @c{bodyform} part of a @c{condition-case} expression
#     determines what should happen when everything works correctly.
    En resumen, la parte @c{bodyform} de una expresión @c{condition-case}
    determina qué deberia suceder cuando todo funciona correctamente.

#     However, if an error occurs, among its other actions, the function
#     generating the error signal will define one or more error condition
#     names.
    Sin embargo, si ocurre un error, entre otras acciones, la función
    genera la señal de error que define uno o más nombres de condicion de error.

#     An error handler is the third argument to @c{condition case}. An error
#     handler has two parts, a @c{condition-name} and a @c{body}. If the
#     @c{condition-name} part of an error handler matches a condition name
#     generated by an error, then the @c{body} part of the error handler is
#     run.
    El gestor de errores es el tercer argumento de @c{condition-case}. Un gestor
    de errores tiene dos partes, un @c{nombre-de-condicion} y un @c{cuerpo}. Si
    la parte @c{nombre-de-condicion} de un gestor de errores coincide con un
    nombre de condicion generado por un error, se ejecuta la parte del
    @c{cuerpo} del gestor de errores.

#     As you will expect, the @c{condition-name} part of an error handler may
#     be either a single condition name or a list of condition names.
    Como es de esperar, la parte @c{nombre-de-condicion} de un gestor de errores
    puede ser un unico nombre de condicion o una lista de nombres de condición.

#     Also, a complete @c{condition-case} expression may contain more than one
#     error handler. When an error occurs, the first applicable handler is
#     run.
    Ademas, una expresión @c{condition-case} completa puede contener más de un
    gestor de errores. Cuando se produce un error, se ejecuta el primer
    gestor aplicable.

#     Lastly, the first argument to the @c{condition-case} expression, the
#     @c{var} argument, is sometimes bound to a variable that contains
#     information about the error. However, if that argument is nil, as is the
#     case in @c{kill-region}, that information is discarded.
    Por ultimo, el primer argumento de la expresión @c{condition-case}, el
    argumento @c{var}, en ocaciones se vincula a una variable que contiene
    información sobre el error. Sin embargo, si este argumento es @c(nil), como
    es el caso en @c{kill-region}, esa información se descarta.

#     In brief, in the @c{kill-region} function, the code @c{condition-case}
#     works like this:
    En resumen, en la función @c{kill-region}, el código @c{condition-case}
    funciona de la siguiente manera:

#     ..example >
#       If no errors, run only this code
#           but, if errors, run this other code.
#     < example..
    ..example >
      Si no hay errores, ejecuta solo este codigo
          pero, si hay errores, ejecuta este otro codigo.
    < example..

# *** Lisp macro
*** Macro Lisp

#     The part of the @c{condition-case} expression that is evaluated in the
#     expectation that all goes well has a @c{when}. The code uses @c{when} to
#     determine whether the @c{string} variable points to text that exists.
    La parte de la expresión @c{condition-case} se evalúa con la expectativa
    de que todo va bien si tiene un @c{when}. El código utiliza @c{when} para
    determinar si la variable @c{string} apunta a texto que existe.

#     A @c{when} expression is simply a programmers' convenience. It is an
#     @c{if} without the possibility of an else clause. In your mind, you can
#     replace @c{when} with @c{if} and understand what goes on. That is what
#     the Lisp interpreter does.
    Una expresión @c{when} simplemente es una conveniencia para los
    programadores. Es un @c{if} sin la posibilidad de una cláusula else. En tu
    mente, puedes reemplazar @c{when} con @c{if} y entender lo que pasa. Eso es
    lo que hace el intérprete Lisp.

#     Technically speaking, @c{when} is a Lisp macro. A Lisp @:{macro} enables
#     you to define new control constructs and other language features. It
#     tells the interpreter how to compute another Lisp expression which will
#     in turn compute the value. In this case, the ‘other expression’ is an
#     @c{if} expression.
    Técnicamente hablando, @c{when} es una macro Lisp. Una @:{macro} Lisp te
    permite definir nuevas construcciones de control y otras caracteristicas de
    lenguaje. Le indica al intérprete cómo calcular otra expresión Lisp que a su
    vez calculara el valor. En este caso, la ‘otra expresión’ es una expresión
    @c{if}.

#     The @c{kill-region} function definition also has an @c{unless} macro; it
#     is the converse of @c{when}. The @c{unless} macro is an @c{if} without a
#     then clause
    La definición de la función @c(kill-region) también tiene una macro
    @c{unless}; es lo contario de @c{when}. La macro @c{unless} es un @c{if} sin
    la cláusula @c(then).

#     For more about Lisp macros, see Section @l{elisp.html#Macros<>Macros}, in
#     @e{The GNU Emacs Lisp Reference Manual}. The C programming language also
#     provides macros. These are different, but also useful.
    Para optener más informacion sobre las macros Lisp, consulta la Seccion
    @l{elisp.html#Macros<>Macros} en @e(El Manual de Referencia de Emacs
    Lisp). El lenguaje de programación C también proporciona macros. Estos son
    diferentes, pero también útiles.

#     Regarding the @c{when} macro, in the @c{condition-case} expression, when
#     the string has content, then another conditional expression is executed.
#     This is an @c{if} with both a then-part and an else-part.
    Respecto a la macro @c{when}, en la expresión @c{condition-case}, cuando la
    cadena tiene contenido, se ejecuta otra expresión condicional. Esto es un
    @c{if} tanto con la parte-then como con la parte-else.

#     ..src > elisp
#       (if (eq last-command 'kill-region)
#           (kill-append string (< end beg) yank-handler)
#         (kill-new string nil yank-handler))
#     < src..
    ..src > elisp
      (if (eq last-command 'kill-region)
          (kill-append string (< end beg) yank-handler)
        (kill-new string nil yank-handler))
    < src..

#     The then-part is evaluated if the previous command was another call to
#     @c{kill-region}; if not, the else-part is evaluated.
    La parte-then se evalúa si el comando anterior era otra llamada
    a @c{kill-region}; si no, se evalúa la parte-else.

#     @c{yank-handler} is an optional argument to @c{kill-region} that tells
#     the @c{kill-append} and @c{kill-new} functions how deal with properties
#     added to the text, such as ‘bold’ or ‘italics’.
    @c{yank-handler} es un argumento opcional de @c{kill-region} que indica a
    las funciones @c{kill-append} y @c{kill-new} como tratar con propiedades
    añadidas al texto, como ‘negrilla’ o ‘cursiva’.

#     @c{last-command} is a variable that comes with Emacs that we have not
#     seen before. Normally, whenever a function is executed, Emacs sets the
#     value of @c{last-command} to the previous command.
    @c{last-command} es una variable que viene con Emacs y que no hemos visto
    antes. Normalmente, siempre que se ejecuta una función, Emacs establece el
    valor de @c{last-command} al comando anterior.

#     In this segment of the definition, the @c{if} expression checks whether
#     the previous command was @c{kill-region}. If it was,
    En este segmento de la definición, la expresión @c{if} comprueba si el
    comando anterior fue @c{kill-region}. Si lo fuera,

#     ..src > elisp
#       (kill-append string (< end beg) yank-handler)
#     < src..
    ..src > elisp
      (kill-append string (< end beg) yank-handler)
    < src..

#     concatenates a copy of the newly clipped text to the just previously
#     clipped text in the kill ring.
    concatena una copia del texto recien cortado al texto cortado previamente en
    el anillo de la muerte.

# ** @c{copy-region-as-kill}
** @c{copy-region-as-kill}

#    The @c{copy-region-as-kill} function copies a region of text from a buffer
#    and (via either @c{kill-append} or @c{kill-new}) saves it in the
#    @c{kill-ring}.
   La función @c{copy-region-as-kill} copia una región de texto de un búfer
   y (via @c{kill-append} o @c{kill-new}) lo guarda en el @c{kill-ring}.

#    If you call @c{copy-region-as-kill} immediately after a @c{kill-region}
#    command, Emacs appends the newly copied text to the previously copied
#    text. This means that if you yank back the text, you get it all, from
#    both this and the previous operation. On the other hand, if some other
#    command precedes the @c{copy-region-as-kill}, the function copies the text
#    into a separate entry in the kill ring.
   Si llamas a @c{copy-region-as-kill} inmediatamente después de un comando
   @c{kill-region}, Emacs agregara el texto recien copiado al texto copiado
   previamente. Esto significa que traes el texto, lo obtienes todo, tanto de
   esta operacion como de la anterior. Por otra parte, si algún otro comando
   precede a @c{copy-region-as-kill}, la función copia el texto dentro de una
   entrada separada en el anillo de la muerte.

#    Here is the complete text of the version 22 @c{copy-region-as-kill}
#    function:
   Aquí está el texto completo de la función @c{copy-region-as-kill} de la
   versión 22:

#    ..src > elisp
   ..src > elisp
#      (defun copy-region-as-kill (beg end)
     (defun copy-region-as-kill (beg end)
#        "Save the region as if killed, but don't kill it.
#      In Transient Mark mode, deactivate the mark.
#      If ‘interprogram-cut-function’ is non-nil, also save the text for a window
#      system cut and paste."
       "Guarda la region como si fuese cortada, pero no la corta.
     En el modo Transient Mark, desactiva la marca.
     Si ‘interprogram-cut-function’ es no-nil, tambien guarda el texto para un
     sistema de ventana cortar y pegar."
#        (interactive "r")
#        (if (eq last-command 'kill-region)
#            (kill-append (filter-buffer-substring beg end) (< end beg))
#          (kill-new (filter-buffer-substring beg end)))
#        (if transient-mark-mode
#            (setq deactivate-mark t))
#        nil)
       (interactive "r")
       (if (eq last-command 'kill-region)
           (kill-append (filter-buffer-substring beg end) (< end beg))
         (kill-new (filter-buffer-substring beg end)))
       (if transient-mark-mode
           (setq deactivate-mark t))
       nil)
#    < src..
   < src..

#    As usual, this function can be divided into its component parts:
   Como de costumbre, esta función puede dividirse en las partes que la
   componen:

#    ..src > elisp
#      (defun copy-region-as-kill (argument-list)
#        "documentation…"
#        (interactive "r")
#        body…)
#    < src..
   ..src > elisp
     (defun copy-region-as-kill (lista-de-argumentos)
       "documentacion…"
       (interactive "r")
       cuerpo…)
   < src..

#    The arguments are @c{beg} and @c{end} and the function is interactive with
#    @c{"r"}, so the two arguments must refer to the beginning and end of the
#    region. If you have been reading though this document from the beginning,
#    understanding these parts of a function is almost becoming routine.
   Los argumentos son @c{beg} y @c{end} y la función es interactiva con @c{"r"},
   por lo que los dos argumentos deben referirse al inicio y al final de la
   región. Si has estado leyendo este documento desde el principio, entender
   estas partes de una función se esta convirtiendo en algo rutinario.

#    The documentation is somewhat confusing unless you remember that the word
#    ‘kill’ has a meaning different from usual. The ‘Transient Mark’ and
#    @c{interprogram-cut-function} comments explain certain side-effects.
   En la documentación, los comentarios de ‘Transient Mark’ e
   @c{interprogram-cut-function} explican ciertos efectos secundarios.

#    After you once set a mark, a buffer always contains a region. If you
#    wish, you can use Transient Mark mode to highlight the region temporarily.
#    (No one wants to highlight the region all the time, so Transient Mark mode
#    highlights it only at appropriate times. Many people turn off Transient
#    Mark mode, so the region is never highlighted.)
   Después de establecer una marca, un búfer siempre contiene una región. Si lo
   deseas puedes utilizar el modo Transient Mark para resaltar temporalmente la
   región. (Nadie quiere resaltar la región todo el tiempo, por lo que el modo
   Trasient Mark lo resalta solo en los momentos apropiados. Muchas personas
   desactivan el modo Transient Mark, por lo que la región nunca se resalta.)

#    Also, a windowing system allows you to copy, cut, and paste among
#    different programs. In the X windowing system, for example, the
#    @c{interprogram-cut-function} function is @c{x-select-text}, which works
#    with the windowing system's equivalent of the Emacs kill ring.
   Ademas, un sistema de ventanas permite copiar, cortar y pegar entre diferentes
   programas. En el sistema de ventanas X, por ejemplo, la función
   @c{interprogram-cut-function} es @c{x-select-text}, que funciona con el
   sistema de ventanas equivalente al anillo de la muerte de Emacs.

#    The body of the @c{copy-region-as-kill} function starts with an @c{if}
#    clause. What this clause does is distinguish between two different
#    situations: whether or not this command is executed immediately after a
#    previous @c{kill-region} command. In the first case, the new region is
#    appended to the previously copied text. Otherwise, it is inserted into
#    the beginning of the kill ring as a separate piece of text from the
#    previous piece.
   El cuerpo de la función @c{copy-region-as-kill} inicia con una cláusula
   @c{if}. Lo que esta cláusula hace es distinguir entre dos situaciones
   diferentes: si este comando se ejecuta o no inmediatamente después de un
   comando @c{kill-region} anterior. En el primer caso, la nueva región se
   concatena al texto copiado previamente. De lo contrario, se inserta al inicio
   del anillo de la muerte como una pieza de texto separada de la anterior.

#    The last two lines of the function prevent the region from lighting up if
#    Transient Mark mode is turned on.
   Las dos ultimas líneas de la función impiden que la región se ilumine si el
   modo Transient Mark está activo.

#    The body of @c{copy-region-as-kill} merits discussion in detail.
   El cuerpo de @c{copy-region-as-kill} merece ser discutido en detalle.

# *** The Body of @c{copy-region-as-kill}
*** El cuerpo de @c{copy-region-as-kill}

#     The @c{copy-region-as-kill} function works in much the same way as the
#     @c{kill-region} function. Both are written so that two or more kills in
#     a row combine their text into a single entry. If you yank back the text
#     from the kill ring, you get it all in one piece. Moreover, kills that
#     kill forward from the current position of the cursor are added to the end
#     of the previously copied text and commands that copy text backwards add
#     it to the beginning of the previously copied text. This way, the words
#     in the text stay in the proper order.
    @c{copy-region-as-kill} funciona de un modo parecido a la función
    @c{kill-region}. Ambas están escritas de manera que dos o más cortes en una
    fila combinan su texto en una sola entrada. Si sacas el texto del anillo de
    la muerte, se optiene todo en una sola pieza. Ademas, las funciones que cortan
    hacia adelante desde la posición actual del cursor se añaden al final del
    texto copiado previamente y los comandos que cortan el texto hacia atrás lo
    añaden al principio del texto copiado previamente. De esta manera, las
    palabras del texto permanecen en el orden correcto.

#     Like @c{kill-region}, the @c{copy-region-as-kill} function makes use of
#     the @c{last-command} variable that keeps track of the previous Emacs
#     command.
    Al igual que @c{kill-region}, la función @c{copy-region-as-kill} hace uso de
    la variable @c{last-command} que mantiene un seguimiento del comando Emacs
    anterior.

#     Normally, whenever a function is executed, Emacs sets the value of
#     @c{this-command} to the function being executed (which in this case would
#     be @c{copy-region-as-kill}). At the same time, Emacs sets the value of
#     @c{last-command} to the previous value of @c{this-command}.
    Normalmente, siempre que se ejecuta una función, Emacs asigna el valor de
    @c{this-command} a la función que se esta ejecutando (que en este caso sería
    @c{copy-region-as-kill}). Al mismo tiempo, Emacs asigna el valor de
    @c{last-command} al valor anterior de @c{this-command}.

#     In the first part of the body of the @c{copy-region-as-kill} function, an
#     @c{if} expression determines whether the value of @c{last-command} is
#     @c{kill-region}. If so, the then-part of the @c{if} expression is
#     evaluated; it uses the @c{kill-append} function to concatenate the text
#     copied at this call to the function with the text already in the first
#     element (the @c{car}) of the kill ring. On the other hand, if the value
#     of @c{last-command} is not @c{kill-region}, then the
#     @c{copy-region-as-kill} function attaches a new element to the kill ring
#     using the @c{kill-new} function.
    En la primer parte del cuerpo de la función @c{copy-region-as-kill}, una
    expresión @c{if} determina si el valor de @c{last-command} es
    @c{kill-region}. Si es así, se evalua la parte-then de la expresión @c{if};
    utiliza la función @c{kill-append} para concatenar el texto copiado en la llamada
    a esta función con el texto que ya esta en el primer elemento (el @c{car} del
    anillo de la muerte. Por otro lado, si el valor de @c{last-command} no es
    @c{kill-region}, entonces la función @c{copy-region-as-kill} asigna un nuevo
    elemento al anillo de la muerte usando la función @c{kill-new}.

#     The @c{if} expression reads as follows; it uses @c{eq}:
    La expresión @c{if} se lee de la siguiente manera; utiliza @c{eq}:

#     ..src > elisp
#       (if (eq last-command 'kill-region)
#           ;; then-part
#           (kill-append  (filter-buffer-substring beg end) (< end beg))
#         ;; else-part
#         (kill-new  (filter-buffer-substring beg end)))
#     < src..
    ..src > elisp
      (if (eq last-command 'kill-region)
          ;; parte-then
          (kill-append  (filter-buffer-substring beg end) (< end beg))
        ;; parte-else
        (kill-new  (filter-buffer-substring beg end)))
    < src..

#     (The @c{filter-buffer-substring} function returns a filtered substring of
#     the buffer, if any. Optionally––the arguments are not here, so neither
#     is done––the function may delete the initial text or return the text
#     without its properties; this function is a replacement for the older
#     @c{buffer-substring} function, which came before text properties were
#     implemented.)
    (La función @c{filter-buffer-substring} devuelve una subcadena filtrada del
    búfer, si existe. Opcionalmente––los argumentos no están aquí, por lo que
    tampoco se hace––la función puede borrar el texto inicial o devolver el
    texto sin sus propiedades; esta función es un reemplazo para la antigua
    función @c{buffer-substring}, que existia antes de que se implementaran las
    propiedades del texto.)

#     The @c{eq} function tests whether its first argument is the same Lisp
#     object as its second argument. The @c{eq} function is similar to the
#     @c{equal} function in that it is used to test for equality, but differs
#     in that it determines whether two representations are actually the same
#     object inside the computer, but with different names.  @c{equal}
#     determines whether the structure and contents of two expressions are the
#     same.
    La función @c{eq} comprueba si su primer argumento es el mismo objeto Lisp que
    su segundo argumento. La función @c{eq} es similar a la función @c{equal}
    que se utiliza para probar la igualdad, pero difiere en que determina si dos
    representaciones son realmente el mismo objeto dentro de la computadora,
    pero con nombres diferentes. @c{equal} determina si la estructura y el
    contenido de dos expresiones son iguales.

#     If the previous command was @c{kill-region}, then the Emacs Lisp
#     interpreter calls the @c{kill-append} function
    Si el comando anterior fue @c{kill-region}, entonces el intérprete Emacs
    Lisp llama a la función @c{kill-append}

# **** The @c{kill-append} function
**** La función @c{kill-append}

#      The @c{kill-append} function looks like this:
     La función @c{kill-new} se ve así:

#      ..src > elisp
#        (defun kill-append (string before-p &optional yank-handler)
#          "Append STRING to the end of the latest kill in the kill ring.
#        If BEFORE-P is non-nil, prepend STRING to the kill.
#        … "
#          (let* ((cur (car kill-ring)))
#            (kill-new (if before-p (concat string cur) (concat cur string))
#                      (or (= (length cur) 0)
#                          (equal yank-handler
#                                 (get-text-property 0 'yank-handler cur)))
#                      yank-handler)))
#      < src..
     ..src > elisp
       (defun kill-append (string before-p &optional yank-handler)
         "Inserta STRING al fin del ultimo corte en el anillo de la muerte.
       Si BEFORE-P no es nil, anexa STRING al corte.
       … "
         (let* ((cur (car kill-ring)))
           (kill-new (if before-p (concat string cur) (concat cur string))
                     (or (= (length cur) 0)
                         (equal yank-handler
                                (get-text-property 0 'yank-handler cur)))
                     yank-handler)))
     < src..

#      The @c{kill-append} function is fairly straightforward. It uses the
#      @c{kill-new} function, which we will discuss in more detail in a moment.
     La función @c{kill-append} es bastante sencilla. Utiliza la función
     @c{kill-new}, que discutiremos con más detalle en un momento.

#      (Also, the function provides an optional argument called
#      @c{yank-handler}; when invoked, this argument tells the function how to
#      deal with properties added to the text, such as ‘bold’ or ‘italics’.)
     (Ademas, la función proporciona un argumento opcional llamado
     @c{yank-handler}; cuando se invoca, este argumento le dice a la función
     cómo tratar con la propiedades añadidas al texto, como ‘negrita’ o
     ‘cursiva’.)

#      It has a @c{let*} function to set the value of the first element of the
#      kill ring to @c{cur}.  (I do not know why the function does not use
#      @c{let} instead; only one value is set in the expression. Perhaps this
#      is a bug that produces no problems?)
     Tiene una función @c{let*} para asignar el valor del primer elemento del
     anillo de la muerte a @c{cur}. (No se por qué la función no utiliza @c{let}
     en su lugar; solo un valor se asigna en la expresión. ¿Tal vez este es un
     bug que no produce problemas?

#      Consider the conditional that is one of the two arguments to
#      @c{kill-new}. It uses @c{concat} to concatenate the new text to the
#      @c{car} of the kill ring. Whether it prepends or appends the text
#      depends on the results of an @c{if} expression:
     Examinemos el condicional proporciana uno de los dos argumentos de @c{kill-new}.
     Utiliza @c{concat} para concatenar el nuevo texto al @c{car} del anillo de
     la muerte. Si agrega el texto antes o despues depende del resultado de la
     expresión @c{if}:

#      ..src > elisp
#        (if before-p                            ; if-part
#            (concat string cur)                 ; then-part
#          (concat cur string))                  ; else-part
#      < src..
     ..src > elisp
       (if before-p                            ; parte-if
           (concat string cur)                 ; parte-then
         (concat cur string))                  ; parte-else
     < src..

#      If the region being killed is before the region that was killed in the
#      last command, then it should be prepended before the material that was
#      saved in the previous kill; and conversely, if the killed text follows
#      what was just killed, it should be appended after the previous text.
#      The @c{if} expression depends on the predicate @c{before-p} to decide
#      whether the newly saved text should be put before or after the
#      previously saved text.
     Si la región a cortar está antes de la región que se cortó en el último
     comando, entonces debería ser puesta antes que el material guardado en el
     corte anterior; y, a la inversa, si el texto que se corto esta despues del
     que se acaba de cortar, debe añadirse después del texto anterior. La expresión
     @c{if} depende del predicado @c{before-p} para decidir si el texto recien
     guardado debe colocarse antes o después del texto anterior.

#      The symbol @c{before-p} is the name of one of the arguments to
#      @c{kill-append}. When the @c{kill-append} function is evaluated, it is
#      bound to the value returned by evaluating the actual argument. In this
#      case, this is the expression @c{(< end beg)}. This expression does not
#      directly determine whether the killed text in this command is located
#      before or after the kill text of the last command; what it does is
#      determine whether the value of the variable @c{end} is less than the
#      value of the variable @c{beg}. If it is, it means that the user is most
#      likely heading towards the beginning of the buffer. Also, the result of
#      evaluating the predicate expression, @c{(< end beg)}, will be true and
#      the text will be prepended before the previous text. On the other hand,
#      if the value of the variable @c{end} is greater than the value of the
#      variable @c{beg}, the text will be appended after the previous text.
     El símbolo @c{before-p} es el nombre de uno de los argumentos para
     @c{kill-append}. Cuando se evalúa la función @c{kill-append}, se asocia al
     valor devuelto evaluando el argumento actual. En este caso, esta es la
     expresión @c{(< end beg)}. Esta expresión no determina directamente si el
     texto cortado en este comando se localiza antes o después del texto cortado
     del último comando; lo que hace es determinar si el valor de la variable
     @c{end} es menor que el valor de la variable @c{beg}. Si es así, significa
     que problamemente el usuario se dirige hacia el principio del búfer. Ademas, el
     resultado de evaluar la expresión del predicado. @c{(< end beg)}, será
     verdadero y el texto se concatena antes del texto anterior. Por otro lado,
     si el valor de la variable @c{end} es mayor que el valor del la variable
     @c{beg}, el texto se agregara después del texto anterior.

#      When the newly saved text will be prepended, then the string with the
#      new text will be concatenated before the old text:
     Cuando el texto recien guardado se antepone, la cadena con el nuevo texto se
     concatena antes que el texto anterior:

#      ..src > elisp
#        (concat string cur)
#      < src..
     ..src > elisp
       (concat string cur)
     < src..

#      But if the text will be appended, it will be concatenated after the old
#      text:
     Pero si el texto será añadido, será concatenado después del texto anterior:

#      ..src > elisp
#        (concat cur string))
#      < src..
     ..src > elisp
       (concat cur string))
     < src..

#      To understand how this works, we first need to review the @c{concat}
#      function. The @c{concat} function links together or unites two strings
#      of text. The result is a string. For example:
     Para entender cómo funciona esto, primero necesitamos revisar la
     función @c{concat}. La función @c{concat} enlaza o une dos cadenas
     de texto. El resultado es una cadena. Por ejemplo:

#      ..srci > elisp
     ..srci > elisp
#        > (concat "abc" "def")
#        "abcdef"
       > (concat "abc" "def")
       "abcdef"
#        > (concat "new "
#        ^         (car '("first element" "second element")))
#        "new first element"
       > (concat "nuevo "
       ^         (car '("primer elemento" "segundo elemento")))
       "nuevo primer elemento"
#        > (concat (car
#        ^         '("first element" "second element")) " modified")
#        "first element modified"
       > (concat (car
       ^         '("primer elemento" "segundo elemento")) " modificado")
       "primer elemento modificado"
#      < srci..
     < srci..

#      We can now make sense of @c{kill-append}: it modifies the contents of
#      the kill ring. The kill ring is a list, each element of which is saved
#      text. The @c{kill-append} function uses the @c{kill-new} function which
#      in turn uses the @c{setcar} function.
     Ahora podemos dar sentido a @c{kill-append}: modifica el contenido del
     anillo de la muerte. El anillo de la muerte es una lista, en la que cada
     elemento almacena texto. La función @c{kill-append} usa la función
     @c{kill-new} que a su vez utiliza la función @c{setcar}.

# **** The @c{kill-new} function
**** La función @c{kill-new}

#      The @c{kill-new} function looks like this:
     La función @c{kill-new} se ve asi:

#      ..src > elisp
     ..src > elisp
#        (defun kill-new (string &optional replace yank-handler)
       (defun kill-new (string &optional replace yank-handler)
#          "Make STRING the latest kill in the kill ring.
#        Set ‘kill-ring-yank-pointer’ to point to it.
         "Hace que STRING sea el último corte en el anillo de la muerte.
       Establece ‘kill-ring-yank-pointer’ para apuntar a el.

#        If ‘interprogram-cut-function’ is non-nil, apply it to STRING.
#        Optional second argument REPLACE non-nil means that STRING will replace
#        the front of the kill ring, rather than being added to the list.
#        …"
       Si ‘interprogram-cut-function’ es no nulo, aplícarlo a STRING.
       El segundo argumento opcional REPLACE no-nulo significa que STRING
        reemplazará el frente del kill ring, en lugar de agregarse a la lista.
       …"
#          (if (> (length string) 0)
#              (if yank-handler
#                  (put-text-property 0 (length string)
#                                     'yank-handler yank-handler string))
#            (if yank-handler
#                (signal 'args-out-of-range
#                        (list string "yank-handler specified for empty string"))))
#          (if (fboundp 'menu-bar-update-yank-menu)
#              (menu-bar-update-yank-menu string (and replace (car kill-ring))))
#          (if (and replace kill-ring)
#              (setcar kill-ring string)
#            (push string kill-ring)
#            (if (> (length kill-ring) kill-ring-max)
#                (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)))
#          (setq kill-ring-yank-pointer kill-ring)
#          (if interprogram-cut-function
#              (funcall interprogram-cut-function string (not replace))))
         (if (> (length string) 0)
             (if yank-handler
                 (put-text-property 0 (length string)
                                    'yank-handler yank-handler string))
           (if yank-handler
               (signal 'args-out-of-range
                       (list string "yank-handler specified for empty string"))))
         (if (fboundp 'menu-bar-update-yank-menu)
             (menu-bar-update-yank-menu string (and replace (car kill-ring))))
         (if (and replace kill-ring)
             (setcar kill-ring string)
           (push string kill-ring)
           (if (> (length kill-ring) kill-ring-max)
               (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)))
         (setq kill-ring-yank-pointer kill-ring)
         (if interprogram-cut-function
             (funcall interprogram-cut-function string (not replace))))
#      < src..
     < src..

#      (Notice that the function is not interactive.)
     (Observa que la función no es interactiva.)

#      As usual, we can look at this function in parts.
     Como de costumbre, podemos ver esta función en partes.

#      The function definition has an optional @c{yank-handler} argument, which
#      when invoked tells the function how to deal with properties added to the
#      text, such as ‘bold’ or ‘italics’. We will skip that.
     La definición de función tiene un argumento opcional @c{yank-handler},
     que cuando se invoca le dice a la función cómo manejar las propiedades
     añadidas al texto, tales como ‘negrita’ o ‘cursiva’. Nos Saltaremos eso.

#      The first line of the documentation makes sense:
     La primer línea de la documentación tiene sentido:

#      ..example >
#        Make STRING the latest kill in the kill ring.
#      < example..
     ..example >
       Hace que STRING sea el último corte en el anillo de la muerte.
     < example..

#      Let's skip over the rest of the documentation for the moment.
     Vamos a saltarnos el resto de la documentación por el momento.

#      Also, let's skip over the initial @c{if} expression and those lines of
#      code involving @c{menu-bar-update-yank-menu}. We will explain them
#      below.
     También, vamos a saltar la expresión @c{if} inicial y las líneas de código
     en @c{menu-bar-update-yank-menu}. Las explicaremos mas tarde.

#      The critical lines are these:
     Las líneas críticas son estas:

#      ..src > elisp
#          (if (and replace kill-ring)
#              ;; then
#              (setcar kill-ring string)
#            ;; else
#          (push string kill-ring)
#            (setq kill-ring (cons string kill-ring))
#            (if (> (length kill-ring) kill-ring-max)
#                ;; avoid overly long kill ring
#                (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)))
#          (setq kill-ring-yank-pointer kill-ring)
#          (if interprogram-cut-function
#              (funcall interprogram-cut-function string (not replace))))
#      < src..
     ..src > elisp
         (if (and replace kill-ring)
             ;; entonces
             (setcar kill-ring string)
           ;; de otra forma
         (push string kill-ring)
           (setq kill-ring (cons string kill-ring))
           (if (> (length kill-ring) kill-ring-max)
               ;; evita desbordar el anillo de la muerte
               (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)))
         (setq kill-ring-yank-pointer kill-ring)
         (if interprogram-cut-function
             (funcall interprogram-cut-function string (not replace))))
     < src..

#      The conditional test is @c{(and replace kill-ring)}. This will be true
#      when two conditions are met: the kill ring has something in it, and the
#      @c{replace} variable is true.
     La prueba condicional es @c{(and replace kill-ring)}. Esto será verdadero
     cuando se cumplan dos condiciones: el anillo de la muerte tiene algo en el,
     y la variable @c{replace} es verdadera.

#      When the @c{kill-append} function sets @c{replace} to be true
#      and when the kill ring has at least one item in it, the @c{setcar}
#      expression is executed:
     Cuando la función @c{kill-append} establece @c{replace} como verdadero y
     cuando el anillo de la muerte tiene al menos un elemento en el, se ejecuta
     la expresión @c{setcar}.

#      ..src > elisp
#        (setcar kill-ring string)
#      < src..
     ..src > elisp
       (setcar kill-ring string)
     < src..

#      The @c{setcar} function actually changes the first element of the
#      @c{kill-ring} list to the value of @c{string}. It replaces the first
#      element.
     La función @c{setcar} realmente cambia el primer elemento de la lista
     @c{kill-ring} al valor de @c{string}. Eso reemplaza el primer
     elemento.

#      On the other hand, if the kill ring is empty, or replace is false, the
#      else-part of the condition is executed:
     Por otro lado, si el anillo de la muerte está vacío, o @c(replace) es
     falso, se ejecuta la parte-else de la condición:

#      ..src > elisp
#        (push string kill-ring)
#      < src..
     ..src > elisp
       (push string kill-ring)
     < src..

#      @c{push} puts its first argument onto the second. It is similar to the
#      older
     @c{push} pone su primer argumento dentro del segundo. Es similar a la
     mas antigua

#      ..src > elisp
#        (setq kill-ring (cons string kill-ring))
#      < src..
     ..src > elisp
       (setq kill-ring (cons string kill-ring))
     < src..

#      or the newer
     o la mas reciente

#      ..src > elisp
#        (add-to-list kill-ring string)
#      < src..
     ..src > elisp
       (add-to-list kill-ring string)
     < src..

#      When it is false, the expression first constructs a new version of the
#      kill ring by prepending @c{string} to the existing kill ring as a new
#      element (that is what the @c{push} does). Then it executes a second
#      @c{if} clause. This second @c{if} clause keeps the kill ring from
#      growing too long.
     Cuando es falso, la expresión primero construye una nueva versión del
     anillo de la muerte, añadiendo @c{string} al anillo como un nuevo elemento
     (que es lo que hace @c{push}). Entonces ejecuta una segunda clausula @c{if}.
     Este segundo @c{if} impide que el anillo de la muerte se haga demaciado largo.

#      Let's look at these two expressions in order.
     Veamos estas dos expresiones en orden.

#      The @c{push} line of the else-part sets the new value of the kill ring
#      to what results from adding the string being killed to the old kill
#      ring.
     La línea @c{push} de la parte-else asigna el nuevo valor del anillo de la
     muerte a los resultados de agregar la cadena que esta siendo cortada al
     viejo anillo de la muerte.

#      We can see how this works with an example.
     Podemos ver cómo funciona esto con un ejemplo.

#      First,
     Primero,

#      ..src > elisp
#        (setq example-list '("here is a clause" "another clause"))
#      < src..
     ..src > elisp
       (setq lista-de-ejemplo '("aqui hay una clausula" "otra clausula"))
     < src..

#      After evaluating this expression with @k{C-x C-e}, you can evaluate
#      @c{example-list} and see what it returns:
     Después de evaluar esta expresión con @k{C-x C-e}, se puede evaluar
     @c{lista-de-ejemplo} y ver que devuelve:

#      ..srci > elisp
#        > example-list
#        ("here is a clause" "another clause")
#      < srci..
     ..srci > elisp
       > lista-de-ejemplo
       ("aquí hay una claúsula" "otra claúsula")
     < srci..

#      Now, we can add a new element on to this list by evaluating the
#      following expression:
     Ahora, podemos agregar un nuevo elemento a esta lista evaluando la
     siguiente expresión:

#      ..src > elisp
#        (push "a third clause" example-list)
#      < src..
     ..src > elisp
       (push "una tercera cláusula" lista-de-ejemplo)
     < src..

#      When we evaluate @c{example-list}, we find its value is:
     Cuando evaluamos @c{lista-de-ejemplo}, encontramos que su valor es:

#      ..srci > elisp
#        > example-list
#        ("a third clause" "here is a clause" "another clause")
#      < srci..
     ..srci > elisp
       > lista-de-ejemplo
       ("una tercera claúsula" "aquí hay una claúsula" "otra claúsula")
     < srci..

#      Thus, the third clause is added to the list by @c{push}.
     Asi pues, la tercer claúsula se añade a la lista con @c{push}.

#      Now for the second part of the @c{if} clause. This expression keeps the
#      kill ring from growing too long. It looks like this:
     Ahora la segunda parte de la claúsula @c{if}. Esta expresión evita que el
     anillo de la muerte crezca demasiado:

#      ..src > elisp
#        (if (> (length kill-ring) kill-ring-max)
#            (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))
#      < src..
     ..src > elisp
       (if (> (length kill-ring) kill-ring-max)
           (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))
     < src..

#      The code checks whether the length of the kill ring is greater than the
#      maximum permitted length. This is the value of @c{kill-ring-max} (which
#      is 60, by default). If the length of the kill ring is too long, then
#      this code sets the last element of the kill ring to @c{nil}. It does
#      this by using two functions, @c{nthcdr} and @c{setcdr}.
     El código comprueba si la longitud del anillo de la muerte es mayor al
     tamaño máximo permitido. Este es el valor de @c{kill-ring-max} (que es 60,
     por defecto). Si el tamaño del anillo de la muerte es demasiado largo,
     entonces este código establece el último elemento del anillo de la muerte a
     @c{nil}. Hace esto usando dos funciones, @c{nthcdr} y @c{setcdr}.

#      We looked at @c{setcdr} earlier (see Section @l{#@c{setcdr}}). It sets
#      the @c{cdr} of a list, just as @c{setcar} sets the @c{car} of a list.
#      In this case, however, @c{setcdr} will not be setting the @c{cdr} of
#      the whole kill ring; the @c{nthcdr} function is used to cause it to set
#      the @c{cdr} of the next to last element of the kill ring––this means
#      that since the @c{cdr} of the next to last element is the last element
#      of the kill ring, it will set the last element of the kill ring.
     Vimos @c{setcdr} anteriormente (ver Seccion @l(#@c{setcdr})). Esto asigna
     el @c{cdr} de una lista, asi como @c{setcar} asigna el @c{car} de una
     lista. En este caso, sin embargo, @c{setcdr} no estará configurando el
     @c{cdr} del anillo de la muerte completo; se usa la función @c{nthcdr} para
     asignar el @c{cdr} del último elemento del anillo de la muerte––esto
     significa que puesto que el @c{cdr} del penultimo elemento es el ultimo
     elmento del anillo de la muerte, establecera el último elemento del anillo
     de la muerte.

#      The @c{nthcdr} function works by repeatedly taking the @c{cdr} of a
#      list––it takes the @c{cdr} of the @c{cdr} of the @c{cdr} … It does
#      this @m{N} times and returns the results.  (See Section @l{#@c(nthcdr)}).
     La función @c{nthcdr} funciona tomando repetidamente el @c{cdr} de una
     lista––toma el @c{cdr} del @c{cdr} del @c{cdr} …. hace esto @m{N} veces y
     devuelve los resultados. (Consulta la Seccion @l{#@c{nthcdr}}.)

#      Thus, if we had a four element list that was supposed to be three
#      elements long, we could set the @c{cdr} of the next to last element to
#      @c{nil}, and thereby shorten the list.  (If you set the last element to
#      some other value than @c{nil}, which you could do, then you would not
#      have shortened the list. See Section @l{#@c{setcdr}}.)
     De este modo, si teniamos una lista de cuatro elementos que supuestamente
     debia tener tres elementos de longitud, podriamos asignar el @c{cdr} del
     elemento siguiente al último a @c{nil}, y asi acortar la lista. (Si se
     asigna el último elemento en algún otro valor distinto a @c{nil}, que se
     podría hacer, entonces no se habría acortado la lista. Consulta la Sección
     @l{#@c{setcdr}}.)

#      You can see shortening by evaluating the following three expressions in
#      turn. First set the value of @c{trees} to @c{(maple oak pine birch)},
#      then set the @c{cdr} of its second @c{cdr} to @c{nil} and then find
#      the value of @c{trees}:
     Puedes ver el acortamiento evaluando las siguientes tres expresiones.
     Primero asigna el valor de @c{arboles} a @c{(arce roble pino abedul)} luego
     establece el @c{cdr} de su segundo @c{cdr} y despues encuentra el valor de
     @c{arboles}.

#      ..srci > elisp
     ..srci > elisp
#        > (setq trees '(maple oak pine birch))
#        (maple oak pine birch)
       > (setq arboles '(arce roble pino abedul))
       (arce roble pino abedul)
#        > (setcdr (nthcdr 2 trees) nil)
#        nil
       > (setcdr (nthcdr 2 arboles) nil)
       nil
#        > trees
#        (maple oak pine)
       > arboles
       (arce roble pino)
#      < srci..
     < srci..

#      (The value returned by the @c{setcdr} expression is @c{nil} since that
#      is what the @c{cdr} is set to.)
     (El valor devuelto por la expresión @c{setcdr} es @c{nil}, ya que en esto
     se establece el @c{cdr}.)

#      To repeat, in @c{kill-new}, the @c{nthcdr} function takes the @c{cdr} a
#      number of times that is one less than the maximum permitted size of the
#      kill ring and @c{setcdr} sets the @c{cdr} of that element (which will
#      be the rest of the elements in the kill ring) to @c{nil}. This prevents
#      the kill ring from growing too long.
     Para repetir, en @c{kill-new}, la función @c{nthcdr} toma el @c{cdr} un
     número de veces, que es uno menos que el tamaño máximo permitido del anillo
     de la muerte y @c{setcdr} establece el @c{cdr} de este elemento (que será el
     resto de los elementos en el anillo de la muerte) en @c{nil}. Esto evita que
     el anillo de la muerte se alargue demaciado.

#      The next to last expression in the @c{kill-new} function is
     La penultima expresión en la función @c{kill-new} es

#      ..src > elisp
#        (setq kill-ring-yank-pointer kill-ring)
#      < src..
     ..src > elisp
       (setq kill-ring-yank-pointer kill-ring)
     < src..

#      The @c{kill-ring-yank-pointer} is a global variable that is set to be
#      the @c{kill-ring}.
     @c{kill-ring-yank-pointer} es una variable global que se establece
     para ser el @c{kill-ring}.

#      Even though the @c{kill-ring-yank-pointer} is called a @'{pointer}, it
#      is a variable just like the kill ring. However, the name has been
#      chosen to help humans understand how the variable is used.
     Apesar de llamar a @c{kill-ring-yank-pointer} un @'{puntero}, es una
     variable al igual que el anillo de la muerte. Sin embargo, el nombre ha
     sido elegido para ayudar a los humanos a entender cómo se usa la variable.

#      Now, to return to an early expression in the body of the function:
     Ahora, volviendo a una expresión anterior en el cuerpo de la función:

#      ..src > elisp
#          (if (fboundp 'menu-bar-update-yank-menu)
#               (menu-bar-update-yank-menu string (and replace (car kill-ring))))
#      < src..
     ..src > elisp
         (if (fboundp 'menu-bar-update-yank-menu)
              (menu-bar-update-yank-menu string (and replace (car kill-ring))))
     < src..

#      It starts with an @c{if} expression
     Empieza con una expresión @c{if}

#      In this case, the expression tests first to see whether
#      @c{menu-bar-update-yank-menu} exists as a function, and if so, calls it.
#      The @c{fboundp} function returns true if the symbol it is testing has a
#      function definition that ‘is not void’. If the symbol's function
#      definition were void, we would receive an error message, as we did when
#      we created errors intentionally (see Section @l{#Generate an Error
#      Message}).
     En este caso, la expresión prueba primero si @c{menu-bar-update-yank-menu}
     existe como una función, y si es así, la llama. La función @c{fboundp}
     devuelve verdadero si el símbolo que se prueba tiene una definición de
     función que ‘no es nula’. Si el símbolo de la definición de función fuera
     nulo, recibiríamos un mensaje de error, como lo hicimos cuando se crearon
     errores intencionadamente (Consulta la Seccion @l(#Generar un mensaje de error)).

#      The then-part contains an expression whose first element is the function
#      @c{and}.
     La parte-entonces contiene una expresión cuyo primer elemento es la función
     @c{and}.

#      The @c{and} special form evaluates each of its arguments until one of
#      the arguments returns a value of @c{nil}, in which case the @c{and}
#      expression returns @c{nil}; however, if none of the arguments returns a
#      value of @c{nil}, the value resulting from evaluating the last argument
#      is returned.  (Since such a value is not @c{nil}, it is considered true
#      in Emacs Lisp.)  In other words, an @c{and} expression returns a true
#      value only if all its arguments are true.  (See Section @l{#A Few More
#      Complex Functions Review<>Second Buffer Related Review}.)
     La forma especial @c{and} evalúa cada uno de sus argumentos hasta que uno
     de los argumentos devuelve un valor de @c{nil}, en cuyo caso la expresión
     @c{and} devuelve @c{nil}; sin embargo, si ninguno de los argumentos
     devuelve una valor @c{nil}, se devuelve el resultado de la evaluación del
     último argumento. (Puesto que tal valor no es @c{nil}, en Emacs Lisp se
     considera verdadero.) En otras palabras, una expresión @c{and} devuelve un
     valor verdadero solo si todos sus argumentos son verdaderos. (Consulta la Seccion
     @l{#Repaso: Algunas Funciones Más Complejas<>Revisar el segundo búfer
     relacionado}.)

#      The expression determines whether the second argument to
#      @c{menu-bar-update-yank-menu} is true or not.
     La expresión determina si el segundo argumento
     @c{menu-bar-update-yank-menu} es verdadero o no.

#      @c{menu-bar-update-yank-menu} is one of the functions that make it
#      possible to use the ‘Select and Paste’ menu in the Edit item of a menu
#      bar; using a mouse, you can look at the various pieces of text you have
#      saved and select one piece to paste.
     @c{menu-bar-update-yank-menu} es una de la funciones que permiten utilizar
     el menu ‘Seleccionar y Pegar’ en el elemento Editar de la barra de menu;
     usando un ratón, puedes ver las distintas piezas de texto que se han
     guardado y seleccionar una pieza para pegar.

#      The last expression in the @c{kill-new} function adds the newly copied
#      string to whatever facility exists for copying and pasting among
#      different programs running in a windowing system. In the X Windowing
#      system, for example, the @c{x-select-text} function takes the string and
#      stores it in memory operated by X. You can paste the string in another
#      program, such as an Xterm.
     La última expresión en la función @c{kill-new} añade la nueva cadena recien
     copiada a cualquier facilidad existente para copiar y pegar texto entre
     diferentes programas que se ejecutan en un sistema de ventanas. En el
     Sistema de Ventanas X, por ejemplo, la función @c{x-select-text} toma la
     cadena y la almacena en la memoria operada por X. Puede pegar la cadena en
     otro programa, como Xterm.

#      The expression looks like this:
     La expresión se ve asi:

#      ..src > elisp
#        (if interprogram-cut-function
#            (funcall interprogram-cut-function string (not replace))))
#      < src..
     ..src > elisp
         (if interprogram-cut-function
             (funcall interprogram-cut-function string (not replace))))
     < src..

#      If an @c{interprogram-cut-function} exists, then Emacs executes
#      @c{funcall}, which in turn calls its first argument as a function and
#      passes the remaining arguments to it.  (Incidentally, as far as I can
#      see, this @c{if} expression could be replaced by an @c{and} expression
#      similar to the one in the first part of the function.)
     Si @c{interprogram-cut-function} existe, entonces Emacs ejecuta
     @c{funcall}, que a su vez llama a su primer argumento como una función y le
     pasa el resto de argumentos. (Por cierto, hasta donde puedo ver,
     esta expresión @c{if} podría reemplazarse por una expresión @c{and} similar
     a la de la primer parte de la función.)

#      We are not going to discuss windowing systems and other programs
#      further, but merely note that this is a mechanism that enables GNU Emacs
#      to work easily and well with other programs.
     No vamos a discutir mas sobre sistemas de ventanas y otros programas, sino
     simplemente indicar que este es un mecanismo que le permite a GNU Emacs
     trabajar bien y fácilmente con otros programas.

#      This code for placing text in the kill ring, either concatenated with an
#      existing element or as a new element, leads us to the code for bringing
#      back text that has been cut out of the buffer––the yank commands.
#      However, before discussing the yank commands, it is better to learn how
#      lists are implemented in a computer. This will make clear such
#      mysteries as the use of the term ‘pointer’. But before that, we will
#      digress into C.
     Este código para colocar texto en el anillo de la muerte, ya sea concatenandolo
     con un elemento existente o como un nuevo, nos brinda la habilidad para
     traer texto que ha sido cortado del búfer––los comandos de corte
     @%i(yank). Sin embargo, antes de discutir los comandos de corte, es mejor
     aprender cómo se implementan las listas en un ordenador. Esto pondra de
     manifiesto misterios como el uso del término ‘puntero’. Pero antes de eso,
     nos desviaremos a C.

# ** Digression into C
** Disgresión dentro de C

#    The @c{copy-region-as-kill} function (see Section
#    @l{#@c{copy-region-as-kill}}) uses the @c{filter-buffer-substring}
#    function, which in turn uses the @c{delete-and-extract-region} function.
#    It removes the contents of a region and you cannot get them back.
   La función @c{copy-region-as-kill} (ver Seccion @l{#@c{copy-region-as-kill}})
   utiliza la función @c{filter-buffer-substring}, que a su vez utiliza la función
   @c{delete-and-extract-region}. Eso elimina el contenido de una región y no se
   puede recuperar.

#    Unlike the other code discussed here, the @c{delete-and-extract-region}
#    function is not written in Emacs Lisp; it is written in C and is one of
#    the primitives of the GNU Emacs system. Since it is very simple, I will
#    digress briefly from Lisp and describe it here.
   A diferencia del otro código discutido aquí, la función @c{delete-and-extract-region}
   no está escrita en Emacs Lisp; está escrita en C y es una de las
   primitivas del sistema GNU Emacs. Puesto que es muy simple, hare una breve digresión
   de Lisp y para describirla aquí.

#    Like many of the other Emacs primitives, @c{delete-and-extract-region} is
#    written as an instance of a C macro, a macro being a template for code.
#    The complete macro looks like this:
   Al igual que muchas de las otras primitivas Emacs, @c{delete-and-extract-region}
   se escribe como una instancia de una macro C, una macro es una plantilla de
   codigo. La macro completa tiene el siguiente aspecto:

#    ..src > c
#      DEFUN ("delete-and-extract-region", Fdelete_and_extract_region,
#             Sdelete_and_extract_region, 2, 2, 0,
#             doc: /* Delete the text between START and END and return it.  */)
#             (Lisp_Object start, Lisp_Object end)
#      {
#        validate_region (&start, &end);
#        if (XINT (start) == XINT (end))
#          return empty_unibyte_string;
#        return del_range_1 (XINT (start), XINT (end), 1, 1);
#      }
#    < src..
   ..src > c
     DEFUN ("delete-and-extract-region", Fdelete_and_extract_region,
            Sdelete_and_extract_region, 2, 2, 0,
            doc: /* Borra el texto entre START y END y lo devuelve.  */)
            (Lisp_Object start, Lisp_Object end)
     {
       validate_region (&start, &end);
       if (XINT (start) == XINT (end))
         return empty_unibyte_string;
       return del_range_1 (XINT (start), XINT (end), 1, 1);
     }
   < src..

#    Without going into the details of the macro writing process, let me point
#    out that this macro starts with the word @c{DEFUN}. The word @c{DEFUN}
#    was chosen since the code serves the same purpose as @c{defun} does in
#    Lisp.  (The @c{DEFUN} C macro is defined in @f{emacs/src/lisp.h}.)
   Sin entrar en los detalles del proceso de escritura de la macro, permitame
   señalar que esta macro comienza con la palabra @c{DEFUN}. Se eligio la
   palabra @c{DEFUN} porque el código tiene el mismo propósito que @c{defun} en
   Lisp. (La macro C @c{DEFUN} se define en @f{emacs/src/lisp.h}.)

#    The word @c{DEFUN} is followed by seven parts inside of parentheses:
   La palabra @c{DEFUN} tiene siete partes dentro de los paréntesis:

#    - The first part is the name given to the function in Lisp,
#      @c{delete-and-extract-region}.
   - La primera parte es el nombre dado a la función en Lisp,
     @c{delete-and-extract-region}.

#    - The second part is the name of the function in C,
#      @c{Fdelete_and_extract_region}. By convention, it starts with @'{F}.
#      Since C does not use hyphens in names, underscores are used instead.
   - La segunda parte es el nombre de la función en C,
     @c{Fdelete_and_extract_region}. Por convención, comienza con @'{F}. Puesto
     que C no usa guiones en los nombres, en su lugar se utilizan guiones bajos.

#    - The third part is the name for the C constant structure that records
#      information on this function for internal use. It is the name of the
#      function in C but begins with an @'{S} instead of an @'{F}.
   - La tercera parte es el nombre para la estructura constante C que
     registra información sobre esta función para uso interno. Es el nombre de
     la función en C pero empieza con una @'{S} en lugar de una @'{F}.

#    - The fourth and fifth parts specify the minimum and maximum number of
#      arguments the function can have. This function demands exactly 2
#      arguments.
   - Las partes cuarta y quinta especifican el número mínimo y máximo de
     argumentos que la función puede tener. Esta función requiere exactamente
     2 argumentos.

#    - The sixth part is nearly like the argument that follows the
#      @c{interactive} declaration in a function written in Lisp: a letter
#      followed, perhaps, by a prompt. The only difference from the Lisp is
#      when the macro is called with no arguments. Then you write a @c{0}
#      (which is a ‘null string’), as in this macro.
   - La sexta parte es casi como el argumento que sigue a la declaración
     @c{interactive} en una función escrita en Lisp: una letra seguida, tal vez,
     por un prompt. La única diferencia con Lisp es cuando se llama a la macro sin
     argumentos. Entonces se escribe un @c{0} (que es una ‘cadena nula’), como
     en esta macro.

#      If you were to specify arguments, you would place them between quotation
#      marks. The C macro for @c{goto-char} includes @c{"NGoto char: "} in
#      this position to indicate that the function expects a raw prefix, in
#      this case, a numerical location in a buffer, and provides a prompt.
     Si fueras a especificar argumentos, se colocarian entre comillas. La macro
     C para @c{goto-char} incluye @c{"NGoto char "} en esta posición se indica
     que la función espera un prefijo sin procesar, en este caso, una localización
     numérica en un búfer, y proporciona un prompt.

#    - The seventh part is a documentation string, just like the one for a
#      function written in Emacs Lisp. This is written as a C comment.  (When
#      you build Emacs, the program @${lib-src/make-docfile} extracts
#      these comments and uses them to make the “real” documentation.)
   - La séptima parte es una cadena de documentación, igual a la de una función
     escrita en Emacs Lisp. Se escribe como un comentario C. (Cuando se construye
     Emacs, el programa @${lib-src/make-docfile} extrae estos comentarios y los
     usa para crear la documentación “real”.)


#    In a C macro, the formal parameters come next, with a statement of what
#    kind of object they are, followed by what might be called the ‘body’ of
#    the macro. For @c{delete-and-extract-region} the ‘body’ consists of the
#    following four lines:
   En una macro C, los parámetros formales vienen a continuacion, con una
   declaracion de que tipo de objeto son, seguido por lo que podría llamarse el
   ‘cuerpo’ de la macro. Para @c{delete-and-extract-region} el ‘cuerpo’ se
   compone de las cuatro líneas siguientes:

#    ..src > c
#      validate_region (&start, &end);
#      if (XINT (start) == XINT (end))
#        return empty_unibyte_string;
#      return del_range_1 (XINT (start), XINT (end), 1, 1);
#    < src..
   ..src > c
     validate_region (&start, &end);
     if (XINT (start) == XINT (end))
       return build_string ("");
     return del_range_1 (XINT (start), XINT (end), 1, 1);
   < src..

#    The @c{validate_region} function checks whether the values passed as the
#    beginning and end of the region are the proper type and are within range.
#    If the beginning and end positions are the same, then return an empty
#    string.
   La función @c{validate_region} comprueba si los valores pasados como el
   principio y fin de la región son del tipo apropiado y estan dentro del
   rango. Si las posiciones de inicio y fin son las mismas, entonces
   devuelve una cadena vacía.

#    The @c{del_range_1} function actually deletes the text. It is a complex
#    function we will not look into. It updates the buffer and does other
#    things. However, it is worth looking at the two arguments passed to
#    @c{del_range}. These are @c{XINT (start)} and @c{XINT (end)}.
   La función @c{del_range_1} borra el texto. Es una función compleja que no
   examinaremos. Actualiza el búfer y hace otras cosas. Sin embargo, vale la
   pena mirar los dos argumentos pasados a @c{del_range}. Estos son @c{XINT
   (start)} y @c{XINT (end)}.

#    As far as the C language is concerned, @c{start} and @c{end} are two
#    integers that mark the beginning and end of the region to be
#    deleted@n{10}.
   Por lo que respecta al lenguaje C, @c{start} y @c{end} son dos enteros que
   marcan el principio y el fin de la región a eliminar@n{10}.

#    In early versions of Emacs, these two numbers were thirty-two bits long,
#    but the code is slowly being generalized to handle other lengths. Three
#    of the available bits are used to specify the type of information; the
#    remaining bits are used as ‘content’.
   En las primeras versiones de Emacs, estos dos números tenian 32 bits de
   longitud, pero el código está lentamente siendo generalizado para manejar
   otras longitudes. Tres de los bits disponibles son usados para especificar el
   tipo de información; los bits restantes se utilizan como ‘contenido’.

#    @c{XINT} is a C macro that extracts the relevant number from the longer
#    collection of bits; the three other bits are discarded.
   @c{XINT} es una macro C que extrae el numero relevante desde una colección
   mas larga de bits; los otros tres bits se descartan.

#    The command in @c{delete-and-extract-region} looks like this:
   El comando en @c{delete-and-extract-region} se ve asi:

#    ..src > c
#      del_range_1 (XINT (start), XINT (end), 1, 1);
#    < src..
   ..src > c
     del_range_1 (XINT (start), XINT (end), 1, 1);
   < src..

#    It deletes the region between the beginning position, @c{start}, and the
#    ending position, @c{end}.
   Borra la región entre la posición inicial, @c{start}, y la posición final,
   @c{end}.

#    From the point of view of the person writing Lisp, Emacs is all very
#    simple; but hidden underneath is a great deal of complexity to make it all
#    work.
   Desde el punto de vista de la persona que escribe Lisp, Emacs es muy simple;
   pero oculta en el fondo mucha complejidad para hacer que todo funcione.

# ** Initializing a Variable with @c{defvar}
** Inicializando una variable con @c{defvar}

#    The @c{copy-region-as-kill} function is written in Emacs Lisp. Two
#    functions within it, @c{kill-append} and @c{kill-new}, copy a region in a
#    buffer and save it in a variable called the @c{kill-ring}. This section
#    describes how the @c{kill-ring} variable is created and initialized using
#    the @c{defvar} special form.
   La función @c{copy-region-as-kill} esta escrita en Emacs Lisp. Dos funciones
   dentro de ella, @c{kill-append} y @c{kill-new}, copian una región en un búfer
   y la guardan en una variable llamada @c{kill-ring}. Esta sección describe
   cómo se crea e inicializa la variable @c{kill-ring} usando la forma especial
   @c{defvar}.

#    (Again we note that the term @c{kill-ring} is a misnomer. The text that
#    is clipped out of the buffer can be brought back; it is not a ring of
#    corpses, but a ring of resurrectable text.)
   (De nuevo, se señala que el término @c{kill-ring} es un mal nombre. El texto
   que se corta del búfer puede ser traido de vuelta; no es un anillo de cadaveres, sino
   un anillo de texto resucitable.)

#    In Emacs Lisp, a variable such as the @c{kill-ring} is created and given
#    an initial value by using the @c{defvar} special form. The name comes
#    from “define variable”.
   En Emacs Lisp, una variable como @c{kill-ring} se crea y se le da un valor inicial
   usando la forma especial @c{defvar}. El nombre proviene de “definir variable”.

#    The @c{defvar} special form is similar to @c{setq} in that it sets the
#    value of a variable. It is unlike @c{setq} in two ways: first, it only
#    sets the value of the variable if the variable does not already have a
#    value. If the variable already has a value, @c{defvar} does not override
#    the existing value. Second, @c{defvar} has a documentation string.
   La forma especial @c{defvar} es similar a @c{setq} en la que se establece el
   valor de una variable. Se diferencia de @c{setq} en dos formas: primero solo
   establece el valor de la variable si la variable no tiene ya un valor. Si la
   variable ya tiene un valor, @c{defvar} no sobreescribe el valor
   existente. Segundo, @c{defvar} tiene una cadena de documentación.

#    (Another special form, @c{defcustom}, is designed for variables that
#    people customize. It has more features than @c{defvar}.  (See Section
#    @l{#Specifying Variables using @c{defcustom}}.)
   (Otra forma especial, @c{defcustom}, está diseñada para variables que las
   personas personalizan. Tiene más funcionalidades que @c{defvar}. (Consulta la
   Sección @l{#Especificar variables usando @c{defcustom}}.)

#    You can see the current value of a variable, any variable, by using the
#    @c{describe-variable} function, which is usually invoked by typing @k{C-h
#    v}. If you type @k{C-h v} and then @c{kill-ring} (followed by @k{RET})
#    when prompted, you will see what is in your current kill ring––this may be
#    quite a lot!  Conversely, if you have been doing nothing this Emacs
#    session except read this document, you may have nothing in it. Also, you
#    will see the documentation for @c{kill-ring}:
   Se puede ver el valor actual de una variable, cualquier variable, usando la
   función @c{describe-variable}, que normalmente se invoca escribiendo @k{C-h
   v}. Si presionas @k{C-h v} y luego escribes @c{kill-ring} (seguido por
   @k{RET}), veras lo que hay actualmente en tu anillo de la muerte––¡puede
   ser bastante grande! Por el contrario, si no has estado haciendo nada en esta
   sesión en Emacs, excepto leer este documento, es posible no tener nada en
   el. Ademas, se verá la documentación de @c{kill-ring}:

#    ..example >
#      Documentation:
#      List of killed text sequences.
#      Since the kill ring is supposed to interact nicely with cut-and-paste
#      facilities offered by window systems, use of this variable should
#      interact nicely with ‘interprogram-cut-function’ and
#      ‘interprogram-paste-function’. The functions ‘kill-new’,
#      ‘kill-append’, and ‘current-kill’ are supposed to implement this
#      interaction; you may want to use them instead of manipulating the kill
#      ring directly.
#    < example..
   ..example >
     Documentación:
     Lista de secuencias de texto muerto.
     Ya que el anillo de la muerte se supone que interactua bien con
     el copia-y-pega que ofrecen los sistemas de ventanas, el uso de
     esta variable debería interactuar bien con las funciones
     ‘interprogram-cut-function’ e ‘interprogram-paste-function’.
     Las funciones ‘kill-new’, ‘kill-append’, y ‘current-kill’ deben
     implementar esta interacción; es posible que desee utilizarlas
     en lugar de manipular el anillo de la muerte directamente.
   < example..

#    The kill ring is defined by a @c{defvar} in the following way:
   El anillo de la muerte es definido por un @c{defvar} del siguiente modo:

#    ..src > elisp
#      (defvar kill-ring nil
#        "List of killed text sequences.
#      …")
#    < src..
   ..src > elisp
     (defvar kill-ring nil
       "Lista de secuencia de texto muerto.
     …")
   < src..

#    In this variable definition, the variable is given an initial value of
#    @c{nil}, which makes sense, since if you have saved nothing, you want
#    nothing back if you give a @c{yank} command. The documentation string is
#    written just like the documentation string of a @c{defun}. As with the
#    documentation string of the @c{defun}, the first line of the documentation
#    should be a complete sentence, since some commands, like @c{apropos},
#    print only the first line of documentation. Succeeding lines should not
#    be indented; otherwise they look odd when you use @k{C-h v}
#    (@c{describe-variable}).
   En esta definición de variable, a la variable se le da un valor inicial de
   @c{nil}, lo que tiene sentido, ya que si no has guardado nada, no quieres
   nada de vuelta al dar un comando @c{yank}. La cadena de documentación se
   escribe igual que la cadena de documentación de un @c{defun}. Al igual que
   con la cadena de documentacion del defun, la primera linea de la
   documentación deberia ser una frase completa, ya que algunos comandos, como
   @c{apropos}, imprimen solo la primer línea de documentación. Las líneas
   sucesivas no deben indentarse; de lo contrario, se veran extrañas cuando se use
   @k{C-h v} @%c(describe-variable).

# *** @c{defvar} and an asterisk
*** @c{defvar} y un asterisco

#     In the past, Emacs used the @c{defvar} special form both for internal
#     variables that you would not expect a user to change and for variables
#     that you do expect a user to change. Although you can still use
#     @c{defvar} for user customizable variables, please use @c{defcustom}
#     instead, since that special form provides a path into the Customization
#     commands.  (See Section @l{#Specifying Variables using @c{defcustom}}.)
    En el pasado, Emacs usaba la forma especial @c{defvar} tanto para variables
    internas que se esperaba que un usuario cambiara como para las que no se
    esperaban cambios de parte del usuario. Aunque todavía se puede usar
    @c{defvar} para variables personalizadas, por favor, utiliza @c{defcustom} en
    su lugar, ya que esa forma especial proporciona una ruta a los comando de
    personalización. (Consulta la Seccion @l{#Especificar variables usando
    @c{defcustom}}.)

#     When you specified a variable using the @c{defvar} special form, you
#     could distinguish a variable that a user might want to change from others
#     by typing an asterisk, @'{*}, in the first column of its documentation
#     string. For example:
    Cuando se especifica una variable utilizando la forma especial @c{defvar},
    se podría distinguir una variable que un usuario puede querer cambiar de
    las demas escribiendo, @'{*}, en la primera columna de su cadena de
    documentación. Por ejemplo:

#     ..src > elisp
#       (defvar shell-command-default-error-buffer nil
#         "*Buffer name for ‘shell-command’ … error output.
#       … ")
#     < src..
    ..src > elisp
      (defvar shell-command-default-error-buffer nil
        "*Nombre de buffer para ‘shell-command’ … salida de error.
      … ")
    < src..

#     You could (and still can) use the @c{set-variable} command to change the
#     value of @c{shell-command-default-error-buffer} temporarily. However,
#     options set using @c{set-variable} are set only for the duration of your
#     editing session. The new values are not saved between sessions. Each
#     time Emacs starts, it reads the original value, unless you change the
#     value within your @f{.emacs} file, either by setting it manually or by
#     using @c{customize}. See Section @l{#Your @f{.emacs} File}.
    Podrías (y todavía puedes) usar el comando @c{set-variable} para cambiar
    temporalmente el valor de @c{shell-command-default-error-buffer}. Sin
    embargo, las opciones configuradas usando @c{set-variable} solo se
    establecen durante la duración de tu sesión actual. Los nuevos valores no se
    guardan entre sesiones. Cada vez que Emacs inicia, lee el valor original, a
    menos que cambie el valor dentro de su fichero @f{.emacs}, ya sea configurándolo
    manualmente o utilizando @c{customize}. Consulta la Seccion @l{#Tu Fichero
    @f{.emacs}}.

#     For me, the major use of the @c{set-variable} command is to suggest
#     variables that I might want to set in my @f{.emacs} file. There are now
#     more than 700 such variables, far too many to remember readily.
#     Fortunately, you can press @k{TAB} after calling the @c{M-x set-variable}
#     command to see the list of variables.  (See Section
#     @l{emacs.html#Examining<>Examining and Setting Variables} in @e(The GNU
#     Emacs Manual).)
    Para mí, el mayor uso del comando @c{set-variable} es sugerir variables que
    se podría querer establecer en mi fichero @f{.emacs}. Ahora hay más de 700
    variables, demasiadas para recordarlas fácilmente. Afortunadamente, se puede
    presionar @k{TAB} después de llamar al comando @c{M-x set-variable} para ver
    la lista de variables. (Consulta la Seccion @l{emacs.html#Examining<>Examinando
    y Configurando Variables} en @e(El Manual de GNU Emacs).)

# ** Review
** Repaso

#    Here is a brief summary of some recently introduced functions.
   Aquí hay un breve resumen de algunas funciones introducidas recientemente.

#    - @c(car), @c(cdr) ::
   - @c(car), @c(cdr) ::

#      @c{car} returns the first element of a list; @c{cdr} returns the second
#      and subsequent elements of a list.
     @c{car} devuelve el primer elemento de una lista; @c{cdr} devuelve el
     segundo y los siguientes elementos de una lista.

#      For example:
     Por ejemplo:

#      ..srci > elisp
#        > (car '(1 2 3 4 5 6 7))
#        1
#        > (cdr '(1 2 3 4 5 6 7))
#        (2 3 4 5 6 7)
#      < srci..
     ..srci > elisp
       > (car '(1 2 3 4 5 6 7))
       1
       > (cdr '(1 2 3 4 5 6 7))
       (2 3 4 5 6 7)
     < srci..

#    - @c(cons) ::
   - @c(cons) ::

#      @c{cons} constructs a list by prepending its first argument to its
#      second argument.
     @c{cons} construye una lista enlazando su primer argumento a su segundo
     argumento.

#      For example:
     Por ejemplo:

#      ..srci > elisp
#        > (cons 1 '(2 3 4))
#        (1 2 3 4)
#      < srci..
     ..srci > elisp
       > (cons 1 '(2 3 4))
       (1 2 3 4)
     < srci..

#    - @c(funcall) ::
   - @c(funcall) ::

#      @c{funcall} evaluates its first argument as a function. It passes its
#      remaining arguments to its first argument.
     @c{funcall} evalúa su primer argumento como una función. Pasa los
     argumentos restantes a su primer argumento.

#    - @c(nthcdr) ::
   - @c(nthcdr) ::

#      Return the result of taking @c{cdr} ‘n’ times on a list. The @m(nᵗʰ)
#      @c{cdr}. The ‘rest of the rest’, as it were.
     Devuelve el resultado de tomar el @c{cdr} ‘n’ veces en una lista. El
     @m(nᵗʰ) @%i(enesimo) @c{cdr}. El ‘resto del resto’, por asi decirlo.

#      For example:
     Por ejemplo:

#      ..srci > elisp
#        > (nthcdr 3 '(1 2 3 4 5 6 7))
#        (4 5 6 7)
#      < srci..
     ..srci > elisp
       > (nthcdr 3 '(1 2 3 4 5 6 7))
       (4 5 6 7)
     < srci..

#    - @c(setcar), @c(setcdr) ::
   - @c(setcar), @c(setcdr) ::

#      @c{setcar} changes the first element of a list; @c{setcdr} changes the
#      second and subsequent elements of a list.
     @c{setcar} cambia el primer elemento de una lista; @c{setcdr} cambia el
     segundo y los siguientes elementos de una lista.

#      For example:
     Por ejemplo:

#      ..srci > elisp
#        > (setq triple '(1 2 3))
#        > (setcar triple '37)
#        > triple
#        (37 2 3)
#        > (setcdr triple '("foo" "bar"))
#        > triple
#        (37 "foo" "bar")
#      < srci..
     ..srci > elisp
       > (setq triple '(1 2 3))
       > (setcar triple '37)
       > triple
       (37 2 3)
       > (setcdr triple '("foo" "bar"))
       > triple
       (37 "foo" "bar")
     < srci..

#    - @c(progn) ::
   - @c(progn) ::

#      Evaluate each argument in sequence and then return the value of the
#      last.
     Evalúa cada argumento en secuencia y luego devuelve el valor del
     último.

#      For example:
     Por ejemplo:

#      ..srci > elisp
#        > (progn 1 2 3 4)
#        4
#      < srci..
     ..srci > elisp
       > (progn 1 2 3 4)
       4
     < srci..

#    - @c(save-restriction) ::
   - @c(save-restriction) ::

#      Record whatever narrowing is in effect in the current buffer, if any,
#      and restore that narrowing after evaluating the arguments.
     Graba cualquier reduccion @%i(narrowing) que esté en efecto en el búfer
     actual, si la hay, y restablece esa reduccion despues de evaluar los
     argumentos.

#    - @c(search-forward) ::
   - @c(search-forward) ::

#      Search for a string, and if the string is found, move point. With a
#      regular expression, use the similar @c{re-search-forward}.  (See Section
#      @l{#Regular Expression Searches}, for an explanation of regular
#      expression patterns and searches.)
     Busca una cadena y, si se encuentra, mueve el punto. De manera similar,
     para una expresión regular utiliza @c{re-search-forward}. (Consulta la Sección
     @l{#Búsqueda de Expresiones Regulares}, para obtener una explicación de los
     patrones y busquedas de expresiones regulares.)

#      @c{search-forward} and @c{re-search-forward} take four arguments:
     @c{search-forward} y @c{re-search-forward} toman cuatro argumentos:

#      1. The string or regular expression to search for.
     1. La cadena o expresión regular a buscar.

#      2. Optionally, the limit of the search.
     2. Opcionalmente, el límite de la búsqueda.

#      3. Optionally, what to do if the search fails, return @c{nil} or an
#         error message.
     3. Opcionalmente, que hacer si la búsqueda falla, devuelve @c{nil} o un
        mensaje de error.

#      4. Optionally, how many times to repeat the search; if negative, the
#         search goes backwards.
     4. Opcionalmente, cuántas veces repetir la búsqueda; si es negativa, la
        búsqueda va hacia atrás.

#    - @c(kill-region), @c(delete-and-extract-region), @c(copy-region-as-kill) ::
   - @c(kill-region), @c(delete-and-extract-region), @c(copy-region-as-kill) ::

#      @c{kill-region} cuts the text between point and mark from the buffer and
#      stores that text in the kill ring, so you can get it back by yanking.
     @c{kill-region} corta el texto entre el punto y la marca del búfer y
     almacena ese texto en el anillo de la muerte, para que puedas recuperarlo
     "tirando" de el.

#      @c{copy-region-as-kill} copies the text between point and mark into the
#      kill ring, from which you can get it by yanking. The function does not
#      cut or remove the text from the buffer.
     @c{copy-region-as-kill} copia el texto entre punto y marca dentro del
     anillo de la muerte. La función no corta ni elimina el texto del búfer.


#      @c{delete-and-extract-region} removes the text between point and mark from
#      the buffer and throws it away. You cannot get it back.  (This is not an
#      interactive command.)
     @c{delete-and-extract-region} elimina el texto entre el punto y la marca del
     búfer. No puede recuperarse. (Este no es un comando interactivo.)

# ** Searching Exercises
** Ejercicios de Busqueda

#    - Write an interactive function that searches for a string. If the search
#      finds the string, leave point after it and display a message that says
#      “Found!”.  (Do not use @c{search-forward} for the name of this function;
#      if you do, you will overwrite the existing version of @c{search-forward}
#      that comes with Emacs. Use a name such as @c{test-search} instead.)
   - Escribe una función interactiva que busque una cadena de texto. Si la
     búsqueda encuentra la cadena, deja el punto después de ella y muestra un
     mensaje que diga “¡Encontrado!”. (No uses @c{search-forward} para el nombre
     de esta función; si lo haces, se sobreescribirá la versión existente de
     @c{search-forward} que viene con Emacs. En su lugar utiliza un nombre como,
     por ejemplo, @c{test-search}.

#    - Write a function that prints the third element of the kill ring in the
#      echo area, if any; if the kill ring does not contain a third element,
#      print an appropriate message.
   - Escribe una función que imprima el tercer elemento del anillo de la muerte
     en el área de eco, si lo hay; si el anillo de la muerte no contiene un
     tercer elemento, imprime un mensaje apropiado.

# * How Lists are Implemented
* Cómo se implementan las listas

#   In Lisp, atoms are recorded in a straightforward fashion; if the
#   implementation is not straightforward in practice, it is, nonetheless,
#   straightforward in theory. The atom @'c{rose}, for example, is recorded as
#   the four contiguous letters @'c{r}, @'c{o}, @'c{s}, @'c{e}. A list, on the
#   other hand, is kept differently. The mechanism is equally simple, but it
#   takes a moment to get used to the idea. A list is kept using a series of
#   pairs of pointers. In the series, the first pointer in each pair points to
#   an atom or to another list, and the second pointer in each pair points to
#   the next pair, or to the symbol @c{nil}, which marks the end of the list.
  En Lisp, los átomos se registran de manera directa, si la implementación no
  es directa en la práctica, es, sin embargo, directa en teoría. El átomo
  @'c{rosa}, por ejemplo, se graba como las cuatro letras contiguas @'c{r}, @'c{o},
  @'c{s}, @'c{a}. Una lista, por otro lado, se guarda de manera diferente. El
  mecanismo es igualmente simple, pero toma un momento acostumbrarse a la
  idea. Una lista se guarda usando una serie de pares de punteros. En las serie,
  el primer puntero de cada par apunta a un átomo o a otra lista, y el segundo
  puntero de cada par apunta al siguiente par, o al símbolo @c{nil}, que marca
  el final de la lista.

#   A pointer itself is quite simply the electronic address of what is pointed
#   to. Hence, a list is kept as a series of electronic addresses.
  Un puntero por sí mismo es simplemente la dirección electrónica de lo que
  se apunta. Por lo tanto, una lista se guarda como una serie de direcciones
  electrónicas.

#   For example, the list @c{(rose violet buttercup)} has three elements,
#   @'c{rose}, @'c{violet}, and @'c{buttercup}. In the computer, the electronic
#   address of @'c{rose} is recorded in a segment of computer memory along with
#   the address that gives the electronic address of where the atom @'c{violet}
#   is located; and that address (the one that tells where @'c{violet} is
#   located) is kept along with an address that tells where the address for the
#   atom @'c{buttercup} is located.
  Por ejemplo, la lista @c{(rosa violeta tulipan)} tiene tres elementos,
  @'c{rosa}, @'c{violeta}, y @'c{tulipan}. En el ordenador, la dirección
  electrónica de @'c{rosa} se registra en un segmento de memoria del ordenador
  junto con la dirección que da la dirección electrónica de donde se encuentra
  el átomo @'c{violeta}; y esta dirección (la que dice donde se localiza
  @'c{violeta}) se guarda junto con una dirección que dice donde se localiza la
  dirección para el átomo @'c{tulipan}.

#   This sounds more complicated than it is and is easier seen in a diagram:
  Esto parece más complicado de lo que es y es más fácil visto en un
  diagrama:

#   ..art >
#      ___ ___      ___ ___      ___ ___
#     |___|___|--> |___|___|--> |___|___|--> nil
#       |            |            |
#       |            |            |
#        --> rose     --> violet   --> buttercup
#   < art..
  ..art >
     ___ ___      ___ ___      ___ ___
    |___|___|--> |___|___|--> |___|___|--> nil
      |            |            |
      |            |            |
      ---> rosa    ---> violeta ---> tulipan
  < art..

#   In the diagram, each box represents a word of computer memory that holds a
#   Lisp object, usually in the form of a memory address. The boxes, i.e., the
#   addresses, are in pairs. Each arrow points to what the address is the
#   address of, either an atom or another pair of addresses. The first box is
#   the electronic address of @'c{rose} and the arrow points to @'c{rose}; the
#   second box is the address of the next pair of boxes, the first part of
#   which is the address of @'c{violet} and the second part of which is the
#   address of the next pair. The very last box points to the symbol @c{nil},
#   which marks the end of the list.
  En el diagrama, cada caja representa una palabra de la memoria del ordenador
  que contiene un objeto Lisp, normalmente en forma de una dirección de
  memoria. Las cajas, es decir, las direcciones, están en pares. Cada flecha
  apunta a la dirección de un átomo u otro par de direcciones. La primer caja es
  la dirección electrónica de @'c{rosa} y la flecha apunta a @'c{rosa}; la segunda
  caja es la dirección del siguiente par de cajas, la primera parte de las
  cuales que es la dirección de @'c{violeta} y la segunda parte es la dirección
  del siguiente par. La última caja apunta al símbolo @c{nil}, que marca el fin
  de la lista.

#   When a variable is set to a list with a function such as @c{setq}, it
#   stores the address of the first box in the variable. Thus, evaluation of
#   the expression
  Cuando una variable se establece en una lista con una función como @c{setq},
  almacena la dirección de la primera caja en la variable. Asi pues, la
  evaluación de la expresión

#   ..src > elisp
#     (setq bouquet '(rose violet buttercup))
#   < src..
  ..src > elisp
    (setq ramo '(rosa violeta tulipan))
  < src..

#   creates a situation like this:
  crea una situación como esta:

#   ..art >
#     bouquet
#          |
#          |     ___ ___      ___ ___      ___ ___
#           --> |___|___|--> |___|___|--> |___|___|--> nil
#                 |            |            |
#                 |            |            |
#                  --> rose     --> violet   --> buttercup
#   < art..
  ..art >
    ramo
      |
      |     ___ ___      ___ ___      ___ ___
       --> |___|___|--> |___|___|--> |___|___|--> nil
             |            |            |
             |            |            |
              --> rosa     --> violeta   --> tulipan
  < art..

#   In this example, the symbol @c{bouquet} holds the address of the first pair
#   of boxes.
  En este ejemplo, el símbolo @c{ramo} contiene la dirección del primer par de
  cajas.

#   This same list can be illustrated in a different sort of box notation like
#   this:
  Esta misma lista puede ser ilustrada en un tipo diferente de notación de
  cajas como este:

#   ..art >
#     bouquet
#      |
#      |    --------------       ---------------       ----------------
#      |   | car   | cdr  |     | car    | cdr  |     | car     | cdr  |
#       -->| rose  |   o------->| violet |   o------->| butter- |  nil |
#          |       |      |     |        |      |     | cup     |      |
#           --------------       ---------------       ----------------
#   < art..
  ..art >
    ramo
      |
      |    --------------       ----------------       --------------------
      |   | car   | cdr  |     | car     | cdr  |     | car         | cdr  |
       -->| rosa  |   o------->| violeta |   o------->| tulipan     | nil  |
          |       |      |     |         |      |     |             |      |
           --------------       ----------------       --------------------
  < art..

#   (Symbols consist of more than pairs of addresses, but the structure of a
#   symbol is made up of addresses. Indeed, the symbol @c{bouquet} consists of
#   a group of address-boxes, one of which is the address of the printed word
#   @'{bouquet}, a second of which is the address of a function definition
#   attached to the symbol, if any, a third of which is the address of the
#   first pair of address-boxes for the list @c{(rose violet buttercup)}, and
#   so on. Here we are showing that the symbol's third address-box points to
#   the first pair of address-boxes for the list.)
  (Los símbolos consisten en más de un par de direcciones, pero la estructura de
  un símbolo esta formado por direcciones. En efecto, el símbolo @c{ramo}
  consiste de un grupo de cajas-de-direcciones, una de las cuales es la
  dirección de la palabra impresa @'{ramo}, la segunda es la dirección de una
  definición de función adjunta al símbolo, si la hubiera, una tercera parte la
  cual es la dirección del primer par de cajas-de-direccion para la lista
  @c{(rosa violeta tulipan)}, y así sucesivamente. Aquí mostraremos que la
  tercera caja de direcciónes del símbolo apunta al primer par de
  cajas-de-direccion de la lista.)

#   If a symbol is set to the @c{cdr} of a list, the list itself is not
#   changed; the symbol simply has an address further down the list.  (In the
#   jargon, @c{car} and @c{cdr} are ‘non-destructive’.)  Thus, evaluation of
#   the following expression
  Si un símbolo se asigna al @c{cdr} de una lista, la lista en sí no cambia; el
  símbolo simplemente tiene una dirección mas abajo en la lista. (En la jerga,
  @c{car} y @c{cdr} son ‘no destructivos’.) De este modo, la evaluacion de la
  siguiente expresión

#   ..src > elisp
#     (setq flowers (cdr bouquet))
#   < src..
  ..src > elisp
    (setq flores (cdr ramo))
  < src..

#   produces this:
  produce esto:

#   ..art >
#     bouquet        flowers
#       |              |
#       |     ___ ___  |     ___ ___      ___ ___
#        --> |   |   |  --> |   |   |    |   |   |
#            |___|___|----> |___|___|--> |___|___|--> nil
#              |              |            |
#              |              |            |
#               --> rose       --> violet   --> buttercup
#   < art..
  ..art >
    ramo        flores
      |              |
      |     ___ ___  |     ___ ___      ___ ___
       --> |   |   |  --> |   |   |    |   |   |
           |___|___|----> |___|___|--> |___|___|--> nil
             |              |            |
             |              |            |
              --> rosa       --> violeta  --> tulipan
  < art..

#   The value of @c{flowers} is @c{(violet buttercup)}, which is to say, the
#   symbol @c{flowers} holds the address of the pair of address-boxes, the
#   first of which holds the address of @c{violet}, and the second of which
#   holds the address of @c{buttercup}.
  El valor de @c{flores} es @c{(violeta tulipan)}, es decir, el símbolo
  @c{flores} contiene la dirección del par de cajas-de-direcciones, la primera
  de las cuales contiene la dirección de @c{violeta}, y la segunda contiene la
  dirección de @c{tulipan}.

#   A pair of address-boxes is called a @:{cons cell} or @:{dotted pair}. See
#   Section @l{elisp.html#Cons Cell Type<>Cons Cell and List Types} in @e{The
#   GNU Emacs Lisp Reference Manual}, and Section @l{elisp.html#Dotted Pair
#   Notation<>Dotted Pair Notation} in @e{The GNU Emacs Lisp Reference Manual},
#   for more information about cons cells and dotted pairs.
  Un par de cajas-de-direcciones se denomina una @:{cons cell} o @:{par de
  puntos}. Consulta la Seccion @l{elisp.html#Cons Cell Type<>Cons Cell y Tipos
  de Lista} en @e(El Manual de Referencia de Emacs Lisp), y @l{elisp.html#Dotted
  Pair Notation<>Notación de Par Punteado} en @e(El Manual de Referencia de
  GNU Emacs Lisp), para más información acerca las cons cells y los pares punteados.

#   The function @c{cons} adds a new pair of addresses to the front of a series
#   of addresses like that shown above. For example, evaluating the expression
  La función @c{cons} añade un nuevo par de direcciones al frente de una serie
  de direcciones como la que se muestra a continuacion. Por ejemplo, evaluar la
  expresión

#   ..src > elisp
#     (setq bouquet (cons 'lily bouquet))
#   < src..
  ..src > elisp
    (setq ramo (cons 'lila ramo))
  < src..

#   produces:
  produce:

#   ..art >
#     bouquet                       flowers
#       |                             |
#       |     ___ ___        ___ ___  |     ___ ___       ___ ___
#        --> |   |   |      |   |   |  --> |   |   |     |   |   |
#            |___|___|----> |___|___|----> |___|___|---->|___|___|--> nil
#              |              |              |             |
#              |              |              |             |
#               --> lily      --> rose       --> violet    --> buttercup
#   < art..
  ..art >
    ramo                       flores
      |                             |
      |     ___ ___        ___ ___  |     ___ ___       ___ ___
       --> |   |   |      |   |   |  --> |   |   |     |   |   |
           |___|___|----> |___|___|----> |___|___|---->|___|___|--> nil
             |              |              |             |
             |              |              |             |
              --> lila      --> rosa       --> violeta    --> tulipan
  < art..

#   However, this does not change the value of the symbol @c{flowers}, as you
#   can see by evaluating the following,
  Sin embargo, esto no cambia el valor del símbolo @c{flores}, como puedes ver
  evaluando lo siguiente,

#   ..src > elisp
#     (eq (cdr (cdr bouquet)) flowers)
#   < src..
  ..src > elisp
    (eq (cdr (cdr ramo)) flores)
  < src..

#   which returns @c{t} for true.
  que devuelve @c{t} por verdadero.

#   Until it is reset, @c{flowers} still has the value @c{(violet buttercup)};
#   that is, it has the address of the cons cell whose first address is of
#   @c{violet}. Also, this does not alter any of the pre-existing cons cells;
#   they are all still there.
  Hasta que se reinicia, @c{flores} todavía tiene el valor @c{(violeta
  tulipan)}; es decir, tiene la dirección de la cons cell cuya primer dirección
  es @c{violeta}. Ademas, esto no altera ninguna de las cons cell
  preexistentes; todas ellas todavía están allí.

#   Thus, in Lisp, to get the @c{cdr} of a list, you just get the address of
#   the next cons cell in the series; to get the @c{car} of a list, you get
#   the address of the first element of the list; to @c{cons} a new element on
#   a list, you add a new cons cell to the front of the list. That is all
#   there is to it!  The underlying structure of Lisp is brilliantly simple!
  De este modo, en Lisp, para obtener el @c{cdr} de una lista, solo tienes que
  obtener la dirección de la siguiente cons cell de la serie; al obtener el
  @c{car} de una lista, se obtiene la dirección del primer elemento de la lista;
  al agregar @%c(cons) un nuevo elemento en una lista, se añade una nueva cons
  cell al frente de la lista. ¡Esto es todo lo que hay! ¡La estructura
  subyacente de Lisp es brillantemente simple!

#   And what does the last address in a series of cons cells refer to?  It is
#   the address of the empty list, of @c{nil}.
  ¿Y a que se refiere la última dirección en una serie de cons cell? Es la
  direccion de la lista vacía, @c{nil}.

#   In summary, when a Lisp variable is set to a value, it is provided with the
#   address of the list to which the variable refers.
  En resumen, cuando una variable Lisp se establece a un valor, se proporciona
  la dirección de la lista a la que se refiere la variable.

# ** Symbols as a Chest of Drawers
** Símbolos como una caja con cajones

#    In an earlier section, I suggested that you might imagine a symbol as
#    being a chest of drawers. The function definition is put in one drawer,
#    the value in another, and so on. What is put in the drawer holding the
#    value can be changed without affecting the contents of the drawer holding
#    the function definition, and vice-verse.
   En una sección anterior, sugeri que se podría imaginar un símbolo como una
   caja con cajones. La definición de función se coloca en un cajón, el valor en
   otro, etcetera. Lo que se pone en el cajón que contiene el valor puede
   cambiarse sin afectar el contenido del cajón que contiene la definicion de
   función, y viceversa.

#    Actually, what is put in each drawer is the address of the value or
#    function definition. It is as if you found an old chest in the attic, and
#    in one of its drawers you found a map giving you directions to where the
#    buried treasure lies.
   En realidad, lo que se pone en la caja es la dirección del valor o definición
   de función. Es como si encontraras un viejo cofre en el ático, y en uno de
   sus compartimentos hallaras un mapa que te indica donde yace el tesoro
   enterrado.

#    (In addition to its name, symbol definition, and variable value, a symbol
#    has a ‘drawer’ for a @:{property list} which can be used to record other
#    information. Property lists are not discussed here; see Section
#    @l{elisp.html#Property Lists<>Property Lists} in @e{The GNU Emacs Lisp Reference Manual}.)
   (Además de su nombre, la definición del símbolo, y un valor de variable, un
   símbolo tiene un ‘cajón’ para una @:{lista de propiedades} que puede utilizar
   para registrar otra información. Las listas de propiedades no se discuten
   aquí; ver la seccion @l{elisp.html#Property Lists<>Listas de Propiedades} en
   @e{El Manual de Referencia de Emacs Lisp}.)

#    Here is a fanciful representation:
   Aquí hay una representación imaginaria:

#    ..art >
#          Chest of Drawers            Contents of Drawers
#
#          __   o0O0o   __
#        /                 \
#       ---------------------
#      |    directions to    |            [map to]
#      |     symbol name     |             bouquet
#      |                     |
#      +---------------------+
#      |    directions to    |
#      |  symbol definition  |             [none]
#      |                     |
#      +---------------------+
#      |    directions to    |            [map to]
#      |    variable value   |             (rose violet buttercup)
#      |                     |
#      +---------------------+
#      |    directions to    |
#      |    property list    |             [not described here]
#      |                     |
#      +---------------------+
#      |/                   \|
#    < art..
   ..art >
         Caja de Cajones            Contenidos de los Cajones

         __   o0O0o   __
       /                 \
      ---------------------
     |    direcciones al   |            [asignar a]
     | nombre del simbolo  |            ramo
     |                     |
     +---------------------+
     |  direcciones a la   |
     |   definición del    |            [nada]
     |    simbolo          |
     +---------------------+
     |    direcciones al   |            [asignar a]
     |   valor de variable |            (rosa violeta tulipan)
     |                     |
     +---------------------+
     |    direcciones a la |
     |lista de propiedades |            [no descrito aquí]
     |                     |
     +---------------------+
     |/                   \|
   < art..

# ** Exercise
** Ejercicio

#    Set @c{flowers} to @c{violet} and @c{buttercup}. Cons two more flowers on
#    to this list and set this new list to @c{more-flowers}. Set the @c{car}
#    of @c{flowers} to a fish. What does the @c{more-flowers} list now
#    contain?
   Asignar @c{flores} a @c{violeta} y @c{tulipan}. Asignar dos flores más en
   esta lista y asignarla a @c{mas-flores}. Asignar el @c{car} de @c{flores} a un
   pez. ¿Qué lista contiene ahora @c{mas-flores}?

# * Yanking Text Back
* Traer de regreso el texto

#   Whenever you cut text out of a buffer with a ‘kill’ command in GNU Emacs,
#   you can bring it back with a ‘yank’ command. The text that is cut out of
#   the buffer is put in the kill ring and the yank commands insert the
#   appropriate contents of the kill ring back into a buffer (not necessarily
#   the original buffer).
  Siempre que cortas texto de un búfer con un comando ‘kill’, puede traerse de
  vuelta con un comando ‘yank’. El texto cortado del búfer es puesto en el
  anillo de la muerte y los comandos yank insertan el contenido apropiado del
  anillo de la muerte en un búfer (no necesariamente el búfer original).

#   A simple @k{C-y} @%c{yank} command inserts the first item from the kill
#   ring into the current buffer. If the @k{C-y} command is followed
#   immediately by @k{M-y}, the first element is replaced by the second
#   element. Successive @k{M-y} commands replace the second element with the
#   third, fourth, or fifth element, and so on. When the last element in the
#   kill ring is reached, it is replaced by the first element and the cycle is
#   repeated.  (Thus the kill ring is called a ‘ring’ rather than just a
#   ‘list’. However, the actual data structure that holds the text is a list.
#   See Section @l{#Appendix B: Handling the Kill Ring}, for the details of how
#   the list is handled as a ring.)
  Un simple comando @k{C-y} @%c(yank) inserta el primer elemento del anillo de
  la muerte en el búfer actual. Si el comando @k{C-y} es seguido
  inmediatamente por @k{M-y}, el primer elemento se reemplaza por el segundo
  elemento. Los sucesivos comandos @k{M-y} reemplazan el segundo elemento con el
  tercer, cuarto, o quinto elemento, y así sucesivamente. Cuando se alcanza el
  último elemento del anillo de la muerte, se reemplaza por el primer elemento y
  el ciclo se repite. (Por la tanto, el anillo de la muerte se llama un ‘anillo’
  en lugar de solo una ‘lista’. Sin embargo, la estructura de datos real que
  contiene el texto es una lista. Consulta la Seccion @l{#Apéndice B: Manejando el
  anillo de la muerte}, para los detalles de cómo se maneja la lista como un
  anillo.)

# ** Kill Ring Overview
** Resumen del anillo de la muerte

#    The kill ring is a list of textual strings. This is what it looks like:
   El anillo de la muerte es una lista de cadenas de texto. Asi es como luce:

#    ..src > elisp
#      ("some text" "a different piece of text" "yet more text")
#    < src..
   ..src > elisp
     ("algún texto" "un texto diferente" "aún más texto")
   < src..

#    If this were the contents of my kill ring and I pressed @k{C-y}, the
#    string of characters saying @'c{some text} would be inserted in this buffer
#    where my cursor is located.
   Si este fuera el contenido de mi anillo de la muerte y pulsara @k{C-y},
   la cadena de caracteres que dice @'c{algún texto} seria insertada en este
   búfer donde se encuentra mi cursor.

#    The @c{yank} command is also used for duplicating text by copying it. The
#    copied text is not cut from the buffer, but a copy of it is put on the
#    kill ring and is inserted by yanking it back.
   El comando @c{yank} también se utiliza para duplicar texto copiándolo. El
   texto copiado no se corta del búfer, sino que se coloca una copia del
   mismo en el anillo de la muerte y se inserta trayendolo de vuelta.

#    Three functions are used for bringing text back from the kill ring:
#    @c{yank}, which is usually bound to @k{C-y}; @c{yank-pop}, which is
#    usually bound to @k{M-y}; and @c{rotate-yank-pointer}, which is used by
#    the two other functions.
   Se utilizan tres funciones para devolver el texto del anillo de la muerte:
   @c{yank}, que normalmente se asocia a @k{C-y}; @c{yank-pop}, que normalmente
   se asocia a @k{M-y}; y @c{rotate-yank-pointer}, que se utiliza por las otras
   dos funciones.

#    These functions refer to the kill ring through a variable called the
#    @c{kill-ring-yank-pointer}. Indeed, the insertion code for both the
#    @c{yank} and @c{yank-pop} functions is:
   Estas funciones se refieren al anillo de la muerte a través de una variable
   llamada @c{kill-ring-yank-pointer}. De hecho, el codigo de inserción para
   ambas funciones @c{yank} y @c{yank-pop} es:

#    ..src > elisp
#      (insert (car kill-ring-yank-pointer))
#    < src..
   ..src > elisp
     (insert (car kill-ring-yank-pointer))
   < src..

#    (Well, no more. In GNU Emacs 22, the function has been replaced by
#    @c{insert-for-yank} which calls @c{insert-for-yank-1} repetitively for
#    each @c{yank-handler} segment. In turn, @c{insert-for-yank-1} strips text
#    properties from the inserted text according to
#    @c{yank-excluded-properties}. Otherwise, it is just like @c{insert}. We
#    will stick with plain @c{insert} since it is easier to understand.)
   (Bueno, ya no más. En GNU Emacs 22, la función ha sido reemplazada por
   @c{insert-for-yank} que llama repetidamente a @c{insert-for-yank-1} para cada
   segmento a @c{yank-handler}. A su vez, @c{insert-for-yank-1} elimina las
   propiedades del texto insertado de acuerdo a @c{yank-excluded-properties}. De
   otro modo, seria como @c{insert}. Nosotros pegaremos con un @c{insert} plano
   puesto que es mas fácil de comprender.)

#    To begin to understand how @c{yank} and @c{yank-pop} work, it is first
#    necessary to look at the @c{kill-ring-yank-pointer} variable.
   Para empezar a comprender cómo funcionan @c{yank} y @c{yank-pop}, primero hay
   que mirar la variable @c{kill-ring-yank-pointer}.

# ** The @c{kill-ring-yank-pointer} Variable
** La variable @c{kill-ring-yank-pointer}

#    @c{kill-ring-yank-pointer} is a variable, just as @c{kill-ring} is a
#    variable. It points to something by being bound to the value of what it
#    points to, like any other Lisp variable.
   @c{kill-ring-yank-pointer} es una variable, de la misma forma que
   @c{kill-ring} es una variable. Apunta a alguna cosa al estar ligada al
   valor de lo que apunta, como cualquier otra variable Lisp.

#    Thus, if the value of the kill ring is:
   De este modo, si el valor del anillo de la muerte es:

#    ..src > elisp
#      ("some text" "a different piece of text" "yet more text")
#    < src..
   ..src > elisp
     ("algún texto" "un texto diferente" "aún más texto")
   < src..

#    and the @c{kill-ring-yank-pointer} points to the second clause, the value
#    of @c{kill-ring-yank-pointer} is:
   y @c{kill-ring-yank-pointer} apunta a la segunda oracion, el valor de
   @c{kill-ring-yank-pointer} es:

#    ..src > elisp
#      ("a different piece of text" "yet more text")
#    < src..
   ..src > elisp
     ("un texto diferente" "aún más texto")
   < src..

#    As explained in the previous chapter (see Section @l{#How Lists are
#    Implemented}), the computer does not keep two different copies of the text
#    being pointed to by both the @c{kill-ring} and the
#    @c{kill-ring-yank-pointer}. The words “a different piece of text” and
#    “yet more text” are not duplicated. Instead, the two Lisp variables point
#    to the same pieces of text. Here is a diagram:
   Como se explico en el capítulo anterior (Consulta la Seccion @l{#Cómo se
   implementan las listas}), el ordenador no guarda dos copias diferentes del
   texto apuntadas tanto por @c{kill-ring} como por @c{kill-ring-yank-pointer}.
   Las palabras “un texto diferente” y “aún más texto” no están duplicadas. En
   su lugar, las dos variables apuntan a las mismas piezas de texto. Aquí hay un
   diagrama:

#    ..art >
#      kill-ring     kill-ring-yank-pointer
#          |               |
#          |      ___ ___  |     ___ ___      ___ ___
#           ---> |   |   |  --> |   |   |    |   |   |
#                |___|___|----> |___|___|--> |___|___|--> nil
#                  |              |            |
#                  |              |            |
#                  |              |             --> "yet more text"
#                  |              |
#                  |               --> "a different piece of text"
#                  |
#                   --> "some text"
#    < art..
   ..art >
     kill-ring     kill-ring-yank-pointer
         |               |
         |      ___ ___  |     ___ ___      ___ ___
          ---> |   |   |  --> |   |   |    |   |   |
               |___|___|----> |___|___|--> |___|___|--> nil
                 |              |            |
                 |              |            |
                 |              |             --> "aún más texto"
                 |              |
                 |               --> "un texto diferente"
                 |
                  --> "algún texto"
   < art..

#    Both the variable @c{kill-ring} and the variable
#    @c{kill-ring-yank-pointer} are pointers. But the kill ring itself is
#    usually described as if it were actually what it is composed of. The
#    @c{kill-ring} is spoken of as if it were the list rather than that it
#    points to the list. Conversely, the @c{kill-ring-yank-pointer} is spoken
#    of as pointing to a list.
   Tanto la variable @c{kill-ring} como @c{kill-ring-yank-pointer} son
   punteros. Pero el anillo de la muerte en sí suele describirse como si fuera
   realmente de lo que esta compuesto. Se habla de @c{kill-ring} como si fuera la
   lista en lugar de ser un puntero a la lista. Por el contrario, se dice que
   @c{kill-ring-yank-pointer} apunta a una lista.

#    These two ways of talking about the same thing sound confusing at first
#    but make sense on reflection. The kill ring is generally thought of as
#    the complete structure of data that holds the information of what has
#    recently been cut out of the Emacs buffers. The
#    @c{kill-ring-yank-pointer} on the other hand, serves to indicate––that is,
#    to ‘point to’––that part of the kill ring of which the first element (the
#    @c{car}) will be inserted.
   Estas dos formas de hablar sobre la misma cosa suenan confusas al principio
   pero tienen sentido tras reflexionar. El anillo de la muerte se piensa
   generalmente como la estructura completa de datos que contiene la información
   de lo que se ha cortado reciéntemente de los búfers de Emacs. Por otra parte,
   @c{kill-ring-yank-pointer}, sirve para indicar––es decir, para ‘apuntar
   a’––esa parte del anillo de la muerte de la cual se inserta el primer
   elemento (el @c{car}).

# ** Exercises with @c{yank} and @c{nthcdr}
** Ejercicios con @c{yank} y @c{nthcdr}

#    - Using @k{C-h v} @%c(describe-variable), look at the value of your kill
#      ring. Add several items to your kill ring; look at its value again.
#      Using @k{M-y} @%c(yank-pop), move all the way around the kill ring.
#      How many items were in your kill ring?  Find the value of
#      @c{kill-ring-max}. Was your kill ring full, or could you have kept more
#      blocks of text within it?
   - Usando @k{C-h v} @%c(describe-variable), mira en el valor de tu anillo de
     la muerte. Añade varios elementos a tu anillo de la muerte; mira su valor
     de nuevo. Usando @k{M-y} @%c{yank-pop}, muevete alrededor del anillo de la
     muerte. ¿Cuántos elementos habia en tu anillo de la muerte? Encuentra el
     valor de @c{kill-ring-max}. ¿Estaba lleno tu anillo de la muerte, o podrías
     haber guardado más bloques de texto dentro en el?

#    - Using @c{nthcdr} and @c{car}, construct a series of expressions to
#      return the first, second, third, and fourth elements of a list.
   - Usando @c{nthcrd} y @c{car}, construye una serie de expresiones para
     devolver el primer, segundo, tercer y cuarto elemento de una lista.

# * Loops and Recursion
* Bucles y recursión

#   Emacs Lisp has two primary ways to cause an expression, or a series of
#   expressions, to be evaluated repeatedly: one uses a @c{while} loop, and the
#   other uses @:{recursion}.
  Emacs Lisp tiene dos formas principales para hacer que una expresión, o una
  serie de expresiones, se evaluen repetidamente: una usa un bucle @c{while},
  y la otra @:{recursión}.

#   Repetition can be very valuable. For example, to move forward four
#   sentences, you need only write a program that will move forward one
#   sentence and then repeat the process four times. Since a computer does not
#   get bored or tired, such repetitive action does not have the deleterious
#   effects that excessive or the wrong kinds of repetition can have on humans.
  La repetición puede ser muy valiosa. Por ejemplo, para avanzar cuatro
  oraciones, solo necesitas escribir un programa que avance una oracion y luego
  repetir el proceso cuatro veces. Ya que un ordenador no se aburre ni se cansa,
  tal acción repetitiva no tiene los efectos nocivos (como un monton de errores)
  que puede tener en los humanos.

#   People mostly write Emacs Lisp functions using @c{while} loops and their
#   kin; but you can use recursion, which provides a very powerful way to think
#   about and then to solve problems@n{11}.
  La mayoria de personas escriben sus funciones de Emacs Lisp usando bucles
  @c{while} y sus parientes; pero se puede usar la recursión, que provee un una
  manera muy poderosa de pensar para resolver problemas@n{11}.

# ** @c{while}
** @c{while}

#    The @c{while} special form tests whether the value returned by evaluating
#    its first argument is true or false. This is similar to what the Lisp
#    interpreter does with an @c{if}; what the interpreter does next, however,
#    is different.
   La forma especial @c{while} prueba si el valor devuelto tras evaluar su
   primer argumento es verdadero o falso. Esto es parecido a lo que el
   intérprete Lisp hace con un @c{if}; sin embargo, lo que el interprete hace
   despues es diferente.

#    In a @c{while} expression, if the value returned by evaluating the first
#    argument is false, the Lisp interpreter skips the rest of the expression
#    (the @:{body} of the expression) and does not evaluate it. However, if
#    the value is true, the Lisp interpreter evaluates the body of the
#    expression and then again tests whether the first argument to @c{while} is
#    true or false. If the value returned by evaluating the first argument is
#    again true, the Lisp interpreter again evaluates the body of the
#    expression.
   En una expresión @c{while}, si el valor devuelto al evaluar el primer
   argumento es falso, el intérprete Lisp omite el resto de la expresión (el
   @:{cuerpo} de la expresión) y no la evalúa. Sin embargo, si el valor es
   verdadero, el intérprete evalúa el cuerpo de la expresión y luego prueba
   nuevamente si el primer argumento de @c{while} es verdadero o falso. Si el
   valor devuelto al evaluar el primer argumento vuelve a ser verdadero, el
   intérprete Lisp vuelve a evaluar el cuerpo de la expresión.

#    The template for a @c{while} expression looks like this:
   La plantilla para una expresión @c{while} luce así:

#    ..src > elisp
#      (while true-or-false-test
#        body…)
#    < src..
   ..src > elisp
     (while prueba-verdadero-o-falso
       cuerpo…)
   < src..

#    So long as the true-or-false-test of the @c{while} expression returns a
#    true value when it is evaluated, the body is repeatedly evaluated. This
#    process is called a loop since the Lisp interpreter repeats the same thing
#    again and again, like an airplane doing a loop. When the result of
#    evaluating the true-or-false-test is false, the Lisp interpreter does not
#    evaluate the rest of the @c{while} expression and ‘exits the loop’.
   Siempre que la evaluacion de prueba-verdadero-o-falso en la expresion
   @c{while} devuelva un valor verdadero, el cuerpo sera evaluado repetidamente.
   Este proceso se llama bucle porque el intérprete Lisp repite lo mismo una y
   otra vez, como un avión haciendo un bucle. Cuando el resultado de evaluar
   prueba-verdadero-o-falso es falso, el intérprete no evalúa el resto de la
   expresión @c{while} y ‘sale del bucle’.

#    Clearly, if the value returned by evaluating the first argument to
#    @c{while} is always true, the body following will be evaluated again and
#    again … and again … forever. Conversely, if the value returned is never
#    true, the expressions in the body will never be evaluated. The craft of
#    writing a @c{while} loop consists of choosing a mechanism such that the
#    true-or-false-test returns true just the number of times that you want the
#    subsequent expressions to be evaluated, and then have the test return
#    false.
   Claramente, si el valor devuelto evaluando el primer argumento de @c{while}
   es siempre cierto, el cuerpo siguiente será evaluado una y otra vez … y otra
   vez … por siempre. Por el contrario, si el valor devuelto nunca es verdadero,
   las expresiones en el cuerpo nunca serán evaluadas. El arte de escribir un
   bucle @c{while} consiste en elegir un mecanismo tal que la
   prueba-verdadero-o-falso devuelva verdadero solo el número de veces que
   requiere evaluar las expresiones subsiguientes, y luego hacer que la prueba
   devuelva falso.

#    The value returned by evaluating a @c{while} is the value of the
#    true-or-false-test. An interesting consequence of this is that a
#    @c{while} loop that evaluates without error will return @c{nil} or false
#    regardless of whether it has looped 1 or 100 times or none at all. A
#    @c{while} expression that evaluates successfully never returns a true
#    value!  What this means is that @c{while} is always evaluated for its side
#    effects, which is to say, the consequences of evaluating the expressions
#    within the body of the @c{while} loop. This makes sense. It is not the
#    mere act of looping that is desired, but the consequences of what happens
#    when the expressions in the loop are repeatedly evaluated.
   El valor devuelto al evaluar un @c{while} es el valor de
   prueba-verdadero-o-falso. Una consecuencia interesante de esto es que un
   bucle @c{while} que se evalúa sin errores devolverá @c{nil} o falso
   independientemente de si ha hecho el bucle 1 o 100 veces o ninguna. ¿Una
   expresión @c{while} que se evalúa con exito nunca devuelve un valor
   verdadero! Lo que esto significa es que @c{while} siempre se evalua por sus
   efectos secundarios, es decir, las consecuencias de evaluar las expresiones
   dentro del cuerpo del bucle. Esto tiene sentido. No es el mero acto del bucle
   lo que se desea, sino las consecuencias de lo que ocurre cuando las
   expresiones en el bucle se evaluan repetidamente.

# *** A @c{while} Loop and a List
*** Un bucle @c{while} y una lista

#     A common way to control a @c{while} loop is to test whether a list has
#     any elements. If it does, the loop is repeated; but if it does not, the
#     repetition is ended. Since this is an important technique, we will
#     create a short example to illustrate it.
    Un forma común para controlar un bucle @c{while} es probar si una lista
    tiene algun elemento. Si es asi, el bucle se repite; pero si no, la
    repetición finaliza. Como esta es una tecnica importante, crearemos un
    ejemplo breve para ilustrarla.

#     A simple way to test whether a list has elements is to evaluate the list:
#     if it has no elements, it is an empty list and will return the empty
#     list, @c{()}, which is a synonym for @c{nil} or false. On the other
#     hand, a list with elements will return those elements when it is
#     evaluated. Since Emacs Lisp considers as true any value that is not
#     @c{nil}, a list that returns elements will test true in a @c{while} loop.
    Un manera sencilla de comprobar si una lista tiene elementos es evaluar la
    lista: si no tiene elementos, se trata de una lista vacía y devuelve la
    lista vacía, @c{()}, que es un sinónimo de @c{nil} o falso. Por otro lado,
    una lista con elementos devolverá estos elementos cuando se evalúe. Ya que
    Emacs Lisp considera como verdadero cualquier valor que no sea @c{nil}, una
    lista que devuelve elementos probara verdadero en un bucle @c{while}.

#     For example, you can set the variable @c{empty-list} to @c{nil} by
#     evaluating the following @c{setq} expression:
    Por ejemplo, se puede asignar la variable @c{lista-vacia} a @c{nil} para
    evaluar la siguiente expresión @c{setq}:

#     ..src > elisp
#       (setq empty-list ())
#     < src..
    ..src > elisp
      (setq lista-vacia ())
    < src..

#     After evaluating the @c{setq} expression, you can evaluate the variable
#     @c{empty-list} in the usual way, by placing the cursor after the symbol
#     and typing @k{C-x C-e}; @c{nil} will appear in your echo area:
    Después de evaluar la expresión @c{setq}, se puede evaluar la variable
    @c{lista-vacia} de la manera habitual, colocando el cursor después del
    símbolo y escribiendo @k{C-x C-e}; aparecerá @c{nil} en tu área de eco:

#     ..src > elisp
#       empty-list
#     < src..
    ..src > elisp
      lista-vacia
    < src..

#     On the other hand, if you set a variable to be a list with elements, the
#     list will appear when you evaluate the variable, as you can see by
#     evaluating the following two expressions:
    Por otro lado, si se asigna una variable como una lista con elementos, la
    lista aparecerá cuando se evalúe la variable, como se puede ver al evaluar
    las dos expresiones siguientes:

#     ..src > elisp
    ..src > elisp
#       (setq animals '(gazelle giraffe lion tiger))
      (setq animales '(gacela jirafa leon tigre))

#       animals
      animales
#     < src..
    < src..

#     Thus, to create a @c{while} loop that tests whether there are any items
#     in the list @c{animals}, the first part of the loop will be written like
#     this:
    De este modo, para crear un bucle @c{while} que pruebe si hay algun elemento
    en la lista @c{animales}, la primera parte del bucle se escribira así:

#     ..src > elisp
#       (while animals
#              …
#     < src..
    ..src > elisp
      (while animales
             …
    < src..

#     When the @c{while} tests its first argument, the variable @c{animals} is
#     evaluated. It returns a list. So long as the list has elements, the
#     @c{while} considers the results of the test to be true; but when the list
#     is empty, it considers the results of the test to be false.
    Cuando @c{while} prueba su primer argumento, la evaluacion de la variable
    @c{animales} devuelve una lista. Mientras la lista tenga elementos, el
    @c{while} considera que el resultado de la prueba es verdadero; pero cuando
    la lista esta vacía, se considera que el resultado de la prueba es falso.

#     To prevent the @c{while} loop from running forever, some mechanism needs
#     to be provided to empty the list eventually. An oft-used technique is to
#     have one of the subsequent forms in the @c{while} expression set the
#     value of the list to be the @c{cdr} of the list. Each time the @c{cdr}
#     function is evaluated, the list will be made shorter, until eventually
#     only the empty list will be left. At this point, the test of the
#     @c{while} loop will return false, and the arguments to the @c{while} will
#     no longer be evaluated.
    Para prevenir que el bucle @c{while} se ejecute para siempre, es necesario
    proporcionar algún mecanismo para vaciar la lista. Una técnica usada con
    frecuencia es tener una de las expresiones en el cuerpo de @c{while} que
    asigne el valor del @c(cdr) de la lista a la lista. Cada vez que se evalua
    la función @c{cdr}, la lista se va reduciendo, hasta que finalmente solo
    queda la lista vacía. En este punto, la prueba del bucle @c{while} devolverá
    falso, y al mismo tiempo los argumentos ya no se evaluarán.

#     For example, the list of animals bound to the variable @c{animals} can be
#     set to be the @c{cdr} of the original list with the following
#     expression:
    Por ejemplo, la lista de animales asociada a la variable @c{animales} puede
    asignarse a el @c{cdr} de la lista original con la siguiente expresión:

#     ..src > elisp
#       (setq animals (cdr animals))
#     < src..
    ..src > elisp
      (setq animales (cdr animales))
    < src..

#     If you have evaluated the previous expressions and then evaluate this
#     expression, you will see @c{(giraffe lion tiger)} appear in the echo
#     area. If you evaluate the expression again, @c{(lion tiger)} will appear
#     in the echo area. If you evaluate it again and yet again, @c{(tiger)}
#     appears and then the empty list, shown by @c{nil}.
    Si has evaluado las expresiones anteriores y luego evaluas esta expresión,
    veras aparecer @c{(jirafa leon tigre)} en el área de eco. Si evalúas la
    expresión de nuevo, aparecera @c{(leon tigre)}. Si la evalúas de nuevo una y
    otra vez, veras @c{(tigre)} y despues la lista vacía, mostrada como @c{nil}.

#     A template for a @c{while} loop that uses the @c{cdr} function repeatedly
#     to cause the true-or-false-test eventually to test false looks like this:
    Una plantilla para un bucle @c{while} usa la función @c{cdr} repetidamente
    para hacer que la prueba-verdadero-o-falso eventualmente se evalue a falso
    como se muesta a continuacion:

#     ..src > elisp
#       (while test-whether-list-is-empty
#         body…
#         set-list-to-cdr-of-list)
#     < src..
    ..src > elisp
      (while prueba-si-la-lista-esta-vacia
        cuerpo…
        establece-lista-al-cdr-de-la-lista)
    < src..

#     This test and use of @c{cdr} can be put together in a function that goes
#     through a list and prints each element of the list on a line of its own.
    Esto prueba y uso de @c{cdr} puede colocarse en una funcion a la que se pase
    una lista e imprima cada elemento de esta en una línea propia.

# *** An Example: @c{print-elements-of-list}
*** Un ejemplo: @c{imprimir-elementos-de-la-lista}

#     The @c{print-elements-of-list} function illustrates a @c{while} loop with
#     a list.
    La función @c{imprimir-elementos-de-la-lista} ilustra un bucle @c{while}
    con una lista.

#     The function requires several lines for its output. If you are reading
#     this in a recent instance of GNU Emacs, you can evaluate the following
#     expression inside of Info, as usual.
    La función requiere varias líneas para su salida. Si estás leyendo esto en
    una instancia reciente de GNU Emacs, puedes evaluarlo de la forma habitual.

#     If you are using an earlier version of Emacs, you need to copy the
#     necessary expressions to your @f{*scratch*} buffer and evaluate them
#     there. This is because the echo area had only one line in the earlier
#     versions.
    Si estas usando una versión antigua de Emacs, es necesario copiar las
    expresiones necesarias en el búfer @f{*scratch*} y evaluarlas allí. Esto se
    debe a que el área de eco solo tenía una línea en las versiones antiguas.

#     You can copy the expressions by marking the beginning of the region with
#     @k{C-SPC} @%c{set-mark-command}, moving the cursor to the end of the
#     region and then copying the region using @k{M-w} (@c{kill-ring-save},
#     which calls @c{copy-region-as-kill} and then provides visual feedback).
#     In the @f{*scratch*} buffer, you can yank the expressions back by typing
#     @k{C-y} @%c{yank}.
    Puedes copiar las expresiones marcando el principio de la región con
    @k{C-SPC} @%c{set-mark-command}, moviendo el cursor al final de la región y
    luego copiar la región usando @k{M-w} (@c{kill-ring-save}, que llama a
    @c{copy-region-as-kill} y proporciona la realimentación visual). En el búfer
    @f{*scratch*}, puedes copiar las expresiones con @k{C-y} @%c{yank}.

#     After you have copied the expressions to the @f{*scratch*} buffer,
#     evaluate each expression in turn. Be sure to evaluate the last
#     expression, @c{(print-elements-of-list animals)}, by typing @k{C-u C-x
#     C-e}, that is, by giving an argument to @c{eval-last-sexp}. This will
#     cause the result of the evaluation to be printed in the @f{*scratch*}
#     buffer instead of being printed in the echo area.  (Otherwise you will
#     see something like this in your echo area:
#     @c{^Jgazelle^J^Jgiraffe^J^Jlion^J^Jtiger^Jnil}, in which each @'{^J}
#     stands for a ‘newline’.)
    Después de copiar las expresiones al búfer @f{*scratch*}, evalúa cada
    expresión en orden. Asegúrate de evaluar la última expresión,
    @c{(imprimir-elementos-de-la-lista animales)}, presionando @k{C-u C-x C-e},
    es decir, pasando un argumento a @c{eval-last-sexp}. Esto hara que el
    resultado de la evaluación se imprima en el búfer @f{*scratch*} en lugar de
    imprimirse en el área de eco. (De lo contrario, veras algo como esto en tu
    área de eco: @c{^Jgacela^J^Jjirafa^J^Jleon^J^Jtigre^Jnil}, en la que cada
    @'{^J} seria una ‘nueva línea’.)

#     In a recent instance of GNU Emacs, you can evaluate these expressions
#     directly in the Info buffer, and the echo area will grow to show the
#     results.
    En una instancia de GNU Emacs reciente, podras evaluar estas expresiones
    directamente, y el área de eco crecerá para mostrar los resultados.

#     ..src > elisp
    ..src > elisp
#       (setq animals '(gazelle giraffe lion tiger))
      (setq animales '(gacela jirafa leon tigre))

#       (defun print-elements-of-list (list)
#         "Print each element of LIST on a line of its own."
#         (while list
#           (print (car list))
#           (setq list (cdr list))))
      (defun imprimir-elementos-de-la-lista (list)
        "Imprime cada elemento de LIST en una línea."
        (while list
          (print (car list))
          (setq list (cdr list))))

#       (print-elements-of-list animals)
      (imprimir-elementos-de-la-lista animales)
#     < src..
    < src..

#     When you evaluate the three expressions in sequence, you will see this:
    Cuando evalúes las tres expresiones en secuencia, verás esto:

#     ..example >
    ..example >
#       gazelle
      gacela

#       giraffe
      jirafa

#       lion
      leon

#       tiger
#       nil
      tigre
      nil
#     < example..
    < example..

#     Each element of the list is printed on a line of its own (that is what
#     the function @c{print} does) and then the value returned by the function
#     is printed. Since the last expression in the function is the @c{while}
#     loop, and since @c{while} loops always return @c{nil}, a @c{nil} is
#     printed after the last element of the list.
    Cada elemento de la lista se imprime en una línea propia (que es lo que hace
    la función @c{print}) y luego se imprime el valor devuelto por la función.
    Como la última expresión de la función es el bucle @c{while}, y como los
    bucles @c{while} siempre devuelven @c{nil}, se imprime un @c{nil} después
    del último elemento de la lista.

# *** A Loop with an Incrementing Counter
*** Un bucle con un contador incremental

#     A loop is not useful unless it stops when it ought. Besides controlling
#     a loop with a list, a common way of stopping a loop is to write the first
#     argument as a test that returns false when the correct number of
#     repetitions are complete. This means that the loop must have a
#     counter––an expression that counts how many times the loop repeats
#     itself.
    Un bucle no es útil a menos que pare cuando debe. Ademas de controlar un
    bucle con una lista, una forma comun de detener un bucle es escribir el
    primer argumento como una prueba que devuelve falso cuando el número
    correcto de repeticiones esta completo. Esto significa que el bucle debe
    tener un contador––una expresión que cuenta cuántas veces el bucle se repite
    a sí mismo.

#     The test for a loop with an incrementing counter can be an expression
#     such as @c{(< count desired-number)} which returns @c{t} for true if the
#     value of @c{count} is less than the @c{desired-number} of repetitions and
#     @c{nil} for false if the value of @c{count} is equal to or is greater
#     than the @c{desired-number}. The expression that increments the count
#     can be a simple @c{setq} such as @c{(setq count (1+ count))}, where
#     @c{1+} is a built-in function in Emacs Lisp that adds 1 to its argument.
#     (The expression @c{(1+ count)} has the same result as @c{(+ count 1)},
#     but is easier for a human to read.)
    La prueba para un bucle con un contador incremental puede ser una expresión
    como @c{(< contador numero-deseado)} que devuelve @c{t} para verdadero si el
    valor de @c{contador} es menor que el @c{numero-deseado} de repeticiones y
    @c{nil} para falso si el valor de @c{contador} es igual o mayor al
    @c{numero-deseado}. La expresión que incrementa el contador puede ser un
    simple @c{setq} como @c{(setq contador (1+ contador))}, donde @c{1+} es una
    función nativa de Emacs Lisp que añade 1 a su argumento. (La expresión
    @c{(1+ contador)} tiene el mismo resultado que @c{(+ contador 1)}, pero es
    mas facil de leer para un humano.)

#     The template for a @c{while} loop controlled by an incrementing counter
#     looks like this:
    La plantilla para un bucle @c{while} controlado por un contador que se
    incrementa se ve asi:

#     ..src > elisp
#       set-count-to-initial-value
#       (while (< count desired-number)         ; true-or-false-test
#         body…
#         (setq count (1+ count)))              ; incrementer
#     < src..
    ..src > elisp
      asignar-un-valor-inicial-al-contador
      (while (< contador numero-deseado)         ; prueba-verdadero-o-falso
        cuerpo…
        (setq contador (1+ contador)))           ; incremento
    < src..

#     Note that you need to set the initial value of @c{count}; usually it is
#     set to 1.
    Ten en cuenta que se necesita asignar el valor inicial de @c{contador}; por
    lo general se asigna en 1.

# **** Example with incrementing counter
**** Ejemplo con contador incremental

#      Suppose you are playing on the beach and decide to make a triangle of
#      pebbles, putting one pebble in the first row, two in the second row,
#      three in the third row and so on, like this:
     Supón que estás jugando en la playa y decides crear un triángulo de
     guijarros, poniendo uno en la primera fila, dos en la segunda fila, tres en
     la tercera fila y así sucesivamente:

#      ..example >
#           •
#          • •
#         • • •
#        • • • •
#      < example..
     ..example >
          •
         • •
        • • •
       • • • •
     < example..

#      (About 2500 years ago, Pythagoras and others developed the beginnings of
#      number theory by considering questions such as this.)
     (Hace 2500 años, Pitágoras y otros desarrollaron los principios de la
     teoría de números al considerar preguntas como esta.)

#      Suppose you want to know how many pebbles you will need to make a
#      triangle with 7 rows?
     Supón que quieres saber cuántos guijarros necesitarás para hacer un
     triángulo con 7 filas

#      Clearly, what you need to do is add up the numbers from 1 to 7. There
#      are two ways to do this; start with the smallest number, one, and add up
#      the list in sequence, 1, 2, 3, 4 and so on; or start with the largest
#      number and add the list going down: 7, 6, 5, 4 and so on. Because both
#      mechanisms illustrate common ways of writing @c{while} loops, we will
#      create two examples, one counting up and the other counting down. In
#      this first example, we will start with 1 and add 2, 3, 4 and so on.
     Claramente, lo que necesitas hacer es sumar los números de 1 a 7. Hay dos
     maneras de hacer esto; se puede comenzar con el numero más pequeño, uno, y
     sumar la lista en secuencia, 1, 2, 3, 4 y así sucesivamente; o empezar con
     el número más grande y sumar la lista hacia abajo: 7, 6, 5, 4 y así
     sucesivamente. Debido a que ambos mecanismos ilustran formas comunes de escribir
     el bucle @c{while}, crearemos dos ejemplos, uno contando hacia arriba y el
     otro contando hacia abajo. En este primer ejemplo, empezaremos con 1 y
     sumaremos 2, 3, 4, etc.

#      If you are just adding up a short list of numbers, the easiest way to do
#      it is to add up all the numbers at once. However, if you do not know
#      ahead of time how many numbers your list will have, or if you want to be
#      prepared for a very long list, then you need to design your addition so
#      that what you do is repeat a simple process many times instead of doing
#      a more complex process once.
     Si quieres sumar toda una lista de números, el camino más fácil de hacerlo
     es sumar todos los números a la vez. Sin embargo, si no se sabe de antemano
     cuántos números tendrá la lista, o si se requiere estar preparado para una
     lista muy larga, entonces se necesita diseñar la suma de manera que lo que
     haga sea repetir un proceso simple muchas veces en vez de hacer un proceso
     más complejo una solo vez.

#      For example, instead of adding up all the pebbles all at once, what you
#      can do is add the number of pebbles in the first row, 1, to the number
#      in the second row, 2, and then add the total of those two rows to the
#      third row, 3. Then you can add the number in the fourth row, 4, to the
#      total of the first three rows; and so on.
     Por ejemplo, en lugar de sumar todos los guijaros a la vez, lo que se puede
     hacer es sumar el número de guijarros en la primera fila, 1, al número de
     la segunda fila, 2, y entonces añadir el total de estas dos filas a la
     tercera fila, 3. Luego se puede sumar el número en la cuarta fila, 4, al
     total de las primeras tres filas; y así sucesivamente.

#      The critical characteristic of the process is that each repetitive
#      action is simple. In this case, at each step we add only two numbers,
#      the number of pebbles in the row and the total already found. This
#      process of adding two numbers is repeated again and again until the last
#      row has been added to the total of all the preceding rows. In a more
#      complex loop the repetitive action might not be so simple, but it will
#      be simpler than doing everything all at once.
     La característica crítica del proceso es que cada acción repetitiva sea
     simple. En este caso, en cada paso se suman solo dos números, el número de
     guijarros en la fila y el total ya encontrado. Este proceso de sumar dos
     números se repite una y otra vez hasta que la última fila ha sido añadida
     al total de todas las filas precedentes. En un bucle más complejo la acción
     repetitiva podría no ser tan sencilla, pero será mas simple que hacerlo
     todo de una sola vez.

# **** The parts of the function definition
**** Las partes de la definición de función

#      The preceding analysis gives us the bones of our function definition:
#      first, we will need a variable that we can call @c{total} that will be
#      the total number of pebbles. This will be the value returned by the
#      function.
     El análisis anterior nos da los huesos de nuestra definición de
     función: primero, necesitaremos una variable que podemos llamar
     @c{total} que será el número total de guijarros. Este será el valor
     devuelto por la función.

#      Second, we know that the function will require an argument: this
#      argument will be the total number of rows in the triangle. It can be
#      called @c{number-of-rows}.
     En segundo lugar, sabemos que la función requerirá un argumento: este
     argumento será el número total de filas del triángulo. Puede llamarse
     @c{numero-de-filas}.

#      Finally, we need a variable to use as a counter. We could call this
#      variable @c{counter}, but a better name is @c{row-number}. That is
#      because what the counter does in this function is count rows, and a
#      program should be written to be as understandable as possible.
     Finalmente, necesitamos una variable para usar como contador. Podriamos
     llamar a esta variable @c{contador}, pero un mejor nombre es
     @c{numero-de-fila}. Esto se debe a que lo que hace el contador en esta
     función es contar filas, y un programa debería escribirse para ser lo mas
     comprensible posible.

#      When the Lisp interpreter first starts evaluating the expressions in the
#      function, the value of @c{total} should be set to zero, since we have
#      not added anything to it. Then the function should add the number of
#      pebbles in the first row to the total, and then add the number of
#      pebbles in the second to the total, and then add the number of pebbles
#      in the third row to the total, and so on, until there are no more rows
#      left to add.
     Cuando el intérprete Lisp comienza a evaluar las expresiones de la función,
     el valor de @c{total} debe ponerse a cero, ya que no hemos sumado nada al
     mismo. Luego la función debe sumar el número de guijarros en la primera
     fila al total, y luego sumar el número de guijarros en la segunda al total,
     y luego sumar el número de guijarros en la tercera fila al total, y así
     sucesivamente, hasta que no queden más filas por sumar.

#      Both @c{total} and @c{row-number} are used only inside the function, so
#      they can be declared as local variables with @c{let} and given initial
#      values. Clearly, the initial value for @c{total} should be 0. The
#      initial value of @c{row-number} should be 1, since we start with the
#      first row. This means that the @c{let} statement will look like this:
     Tanto @c{total} como @c{numero-de-fila} se usan solo dentro de la función,
     por lo que pueden ser declarados como variables locales con @c{let} dando
     sus valores iniciales. Evidentemente, el valor inicial para total
     sera 0. El valor inicial de @c{numero-de-fila} sera 1, ya que comenzaremos
     con la primer fila. Esto significa que la declaracion @c{let} se vera asi:

#      ..src > elisp
#        (let ((total 0)
#              (row-number 1))
#          body…)
#      < src..
     ..src > elisp
       (let ((total 0)
             (numero-de-fila 1))
         cuerpo…)
     < src..

#      After the internal variables are declared and bound to their initial
#      values, we can begin the @c{while} loop. The expression that serves as
#      the test should return a value of @c{t} for true so long as the
#      @c{row-number} is less than or equal to the @c{number-of-rows}.  (If the
#      expression tests true only so long as the row number is less than the
#      number of rows in the triangle, the last row will never be added to the
#      total; hence the row number has to be either less than or equal to the
#      number of rows.)
     Después de declarar y asignar las variables internas, podemos comenzar el
     bucle @c{while}. La expresión que sirve como prueba deberia devolver un
     valor de @c{t} para verdadero siempre que el @c{numero-de-fila} sea menor o
     igual al @c{numero-de-filas}. (Si la prueba devuelve verdadero solo si el
     número de fila es menor que el número de filas en el triángulo, la última
     fila nunca se sumara al total; por lo tanto, el número de fila tiene que
     ser menor o igual al número de filas.)

#      Lisp provides the @c{<=} function that returns true if the value of its
#      first argument is less than or equal to the value of its second argument
#      and false otherwise. So the expression that the @c{while} will evaluate
#      as its test should look like this:
     Lisp proporciona la función @c{<=} que devuelve verdadero si el valor de su
     primer argumento es menor o igual al valor de su segundo argumento y falso
     de lo contrario. Así que la expresión que el @c{while} evaluará como su prueba
     deveria verse asi:

#      ..src > elisp
#        (<= row-number number-of-rows)
#      < src..
     ..src > elisp
       (<= numero-de-fila numero-de-filas)
     < src..

#      The total number of pebbles can be found by repeatedly adding the number
#      of pebbles in a row to the total already found. Since the number of
#      pebbles in the row is equal to the row number, the total can be found by
#      adding the row number to the total.  (Clearly, in a more complex
#      situation, the number of pebbles in the row might be related to the row
#      number in a more complicated way; if this were the case, the row number
#      would be replaced by the appropriate expression.)
     El número total de guijarros se puede encontrar sumando repetidamente el
     número de guijarros en una fila al total ya encontrado. Puesto que el
     número de guijarros en la fila es igual al número de la fila, el total
     puede encontrarse añadiendo el número de filas al total. (Claramente, en
     una situación más compleja, el número de guijarros en la fila podría estar
     relacionado con el número de la fila de una manera más complicada; si este
     fuera el caso, el número de la fila sería reemplazado por la expresión
     apropiada.)

#      ..src > elisp
#        (setq total (+ total row-number))
#      < src..
     ..src > elisp
       (setq total (+ total numero-de-fila))
     < src..

#      What this does is set the new value of @c{total} to be equal to the sum
#      of adding the number of pebbles in the row to the previous total.
     Lo que esto hace es asignar el nuevo valor de @c{total} para que sea igual
     a la suma del número de guijarros en la fila al total anterior.

#      After setting the value of @c{total}, the conditions need to be
#      established for the next repetition of the loop, if there is one. This
#      is done by incrementing the value of the @c{row-number} variable, which
#      serves as a counter. After the @c{row-number} variable has been
#      incremented, the true-or-false-test at the beginning of the @c{while}
#      loop tests whether its value is still less than or equal to the value of
#      the @c{number-of-rows} and if it is, adds the new value of the
#      @c{row-number} variable to the @c{total} of the previous repetition of
#      the loop.
     Después de establecer el valor de @c{total}, se deben establecer las
     condiciones para la siguiente repetición del bucle, si hay alguna. Esto se
     hace incrementando el valor de la variable @c{numero-de-fila}, que sirve
     como contador. Después de incrementar la variable @c{numero-de-fila}, la
     prueba-verdodero-o-falso al principio del bucle @c{while} prueba si su
     valor aun es menor o igual al valor del @c{numero-de-filas} y, si lo es,
     suma el nuevo valor de la variable @c{numero-de-fila} al @c{total} de la
     repetición previa.

#      The built-in Emacs Lisp function @c{1+} adds 1 to a number, so the
#      @c{row-number} variable can be incremented with this expression:
     La función nativa @c{1+} en Emacs Lisp añade 1 a un número, por lo que la
     variable @c{numero-de-fila} puede incrementarse con esta expresión:

#      ..src > elisp
#        (setq row-number (1+ row-number))
#      < src..
     ..src > elisp
       (setq numero-de-fila (1+ numero-de-fila))
     < src..

# **** Putting the function definition together
**** Juntando la definición de función

#      We have created the parts for the function definition; now we need to
#      put them together.
     Hemos creado las partes para la definición de la función; ahora necesitamos
     juntarlas.

#      First, the contents of the @c{while} expression:
     Primero, el contenido de la expresión @c{while}:

#      ..src > elisp
#        (while (<= row-number number-of-rows)   ; true-or-false-test
#          (setq total (+ total row-number))
#          (setq row-number (1+ row-number)))    ; incrementer
#      < src..
     ..src > elisp
       (while (<= numero-de-fila numero-de-filas)    ; prueva-verdadero-o-falso
         (setq total (+ total numero-de-fila))
         (setq numero-de-fila (1+ numero-de-fila)))  ; incremento
     < src..

#      Along with the @c{let} expression varlist, this very nearly completes
#      the body of the function definition. However, it requires one final
#      element, the need for which is somewhat subtle.
     Junto con la expresión @c{let} de la varlist, casi completan el cuerpo de
     la definición de función. Sin embargo, se requiere un ultimo elemento, cuya
     necesidad es algo sutil.

#      The final touch is to place the variable @c{total} on a line by itself
#      after the @c{while} expression. Otherwise, the value returned by the
#      whole function is the value of the last expression that is evaluated in
#      the body of the @c{let}, and this is the value returned by the
#      @c{while}, which is always @c{nil}.
     El toque final es colocar la variable @c{total} en una línea por sí misma
     después de la expresión @c{while}. De lo contrario, el valor devuelto por
     la función completa sera el valor de la última expresión en evaluarse
     dentro del cuerpo del @c{let}, y este es el valor devuelto por el @c{while}
     que es siempre @c{nil}.

#      This may not be evident at first sight. It almost looks as if the
#      incrementing expression is the last expression of the whole function.
#      But that expression is part of the body of the @c{while}; it is the last
#      element of the list that starts with the symbol @c{while}. Moreover,
#      the whole of the @c{while} loop is a list within the body of the
#      @c{let}.
     Esto puede no ser evidente a primera vista. Casi parece como si la
     expresión de incremento fuera la última expresión de la función
     completa. Pero esa expresión es parte del cuerpo del @c{while}; es el
     último elemento de la lista que empieza con el símbolo @c{while}. Ademas,
     todo el bucle @c{while} es una lista dentro del cuerpo del @c{let}.

#      In outline, the function will look like this:
     En el esquema, la función tendra este aspecto:

#      ..src > elisp
#        (defun name-of-function (argument-list)
#          "documentation…"
#          (let (varlist)
#            (while (true-or-false-test)
#              body-of-while… )
#            … ))                    ; Need final expression here.
#      < src..
     ..src > elisp
       (defun nombre-de-la-funcion (lista-de-argumentos)
         "documentacion…"
         (let (varlist)
           (while (prueba-verdadero-o-falso)
             cuerpo-de-while… )
           … ))                    ; aqui necesita la expresión final.
     < src..

#      The result of evaluating the @c{let} is what is going to be returned by
#      the @c{defun} since the @c{let} is not embedded within any containing
#      list, except for the @c{defun} as a whole. However, if the @c{while} is
#      the last element of the @c{let} expression, the function will always
#      return @c{nil}. This is not what we want!  Instead, what we want is the
#      value of the variable @c{total}. This is returned by simply placing the
#      symbol as the last element of the list starting with @c{let}. It gets
#      evaluated after the preceding elements of the list are evaluated, which
#      means it gets evaluated after it has been assigned the correct value for
#      the total.
     El resultado de evaluar el @c{let} es lo que va a ser devuelto por
     @c{defun} ya que @c{let} no está embebido dentro de ninguna lista que la
     contenga, excepto por el @c{defun} como un todo. Sin embargo, si el
     @c{while} es el último elemento de la expresión @c{let}, la función siempre
     devolverá @c{nil}. ¡Esto no es lo que queremos! En vez de eso, queremos el
     valor de la variable @c{total}. Esto se devuelve simplemente colocando el
     símbolo como el último elemento de la lista que comienza con @c{let}. Se
     evalúa después de evaluar los elementos precedentes, lo que significa que
     se evaluó después de que se le ha asignado el valor correcto para el total.

#      It may be easier to see this by printing the list starting with @c{let}
#      all on one line. This format makes it evident that the @c{varlist} and
#      @c{while} expressions are the second and third elements of the list
#      starting with @c{let}, and the @c{total} is the last element:
     Puede ser mas fácil ver esto imprimiendo la lista iniciada por @c{let} en
     una línea. Este formato hace evidente que las expresiones @c{varlist} y
     @c{while} son el segundo y tercer elementos de la lista iniciado por
     @c{let}, y @c{total} es el último elemento:

#      ..src > elisp
#        (let (varlist) (while (true-or-false-test) body-of-while… ) total)
#      < src..
     ..src > elisp
       (let (varlist) (while (prueba-verdadero-o-falso) cuerpo-de-while… ) total)
     < src..

#      Putting everything together, the @c{triangle} function definition looks
#      like this:
     Poniendo todo junto, la definición de la función @c{triangulo} se ve asi:

#      ..src > elisp
#        (defun triangle (number-of-rows)    ; Version with
#                                            ;   incrementing counter.
#          "Add up the number of pebbles in a triangle.
#        The first row has one pebble, the second row two pebbles,
#        the third row three pebbles, and so on.
#        The argument is NUMBER-OF-ROWS."
#          (let ((total 0)
#                (row-number 1))
#            (while (<= row-number number-of-rows)
#              (setq total (+ total row-number))
#              (setq row-number (1+ row-number)))
#            total))
#      < src..
     ..src > elisp
       (defun triangulo (numero-de-filas)  ; Versión con
                                           ;   contador de incremento.
         "Suma el número de guijarros en un triángulo.
       La primera fila tiene un guijarro, la segunda fila dos guijarros,
       la tercera fila tres guijarros, y así sucesivamente.
       El argumento es NUMERO-DE-FILAS."
         (let ((total 0)
               (numero-de-fila 1))
           (while (<= numero-de-fila numero-de-filas)
             (setq total (+ total numero-de-fila))
             (setq numero-de-fila (1+ numero-de-fila)))
           total))
     < src..

#      After you have installed @c{triangle} by evaluating the function, you
#      can try it out. Here are two examples:
     Después de haber instalado @c{triangulo} al evaluar la función, puedes
     probarla. Aquí hay dos ejemplos:

#      ..src > elisp
     ..src > elisp
#        (triangle 4)
       (triangulo 4)

#        (triangle 7)
       (triangulo 7)
#      < src..
     < src..

#      The sum of the first four numbers is 10 and the sum of the first seven
#      numbers is 28.
     La suma de los primeros cuatro números es 10 y la suma de los primeros
     siete números es 28.

# *** Loop with a Decrementing Counter
*** Bucle con un contador decreciente

#     Another common way to write a @c{while} loop is to write the test so that
#     it determines whether a counter is greater than zero. So long as the
#     counter is greater than zero, the loop is repeated. But when the counter
#     is equal to or less than zero, the loop is stopped. For this to work,
#     the counter has to start out greater than zero and then be made smaller
#     and smaller by a form that is evaluated repeatedly.
    Otra manera común de escribir un bucle @c{while} es con una prueba que
    determine si un contador es mayor que cero. Mientras el contador sea mayor
    que cero, el bucle se repite. Pero cuando el contador es igual o menor que
    cero, el bucle se detiene. Para que esto funcione, el contador tiene que
    empezar por encima de cero y luego hacerse mas y mas pequeño mediante una forma
    que se evalue repetidamente.

#     The test will be an expression such as @c{(> counter 0)} which returns
#     @c{t} for true if the value of @c{counter} is greater than zero, and
#     @c{nil} for false if the value of @c{counter} is equal to or less than
#     zero. The expression that makes the number smaller and smaller can be a
#     simple @c{setq} such as @c{(setq counter (1- counter))}, where @c{1-} is
#     a built-in function in Emacs Lisp that subtracts 1 from its argument.
    La prueba será una expresión como @c{(> contador 0)} que devuelve @c{t} para
    verdadero si el valor del @c{contador} es mayor que cero, y @c{nil} para
    falso si el valor del @c{contador} es igual a o menor que cero. La expresión
    que hace que el número menor sea cada vez mas pequeño puede ser un simple
    @c{setq} como @c{(setq contador (1- contador)}, donde @c{1-} es una función
    nativa en Emacs Lisp que resta 1 de su argumento.

#     The template for a decrementing @c{while} loop looks like this:
    La plantilla para un bucle @c{while} decreciente se ve así:

#     ..src > elisp
#       (while (> counter 0)                    ; true-or-false-test
#         body…
#         (setq counter (1- counter)))          ; decrementer
#     < src..
    ..src > elisp
      (while (> contador 0)                   ; prueba-verdadero-o-falso
        cuerpo…
        (setq contador (1- contador)))        ; decremento
    < src..

# **** Example with decrementing counter
**** Ejemplo con contador decreciente

#      To illustrate a loop with a decrementing counter, we will rewrite the
#      @c{triangle} function so the counter decreases to zero.
     Para ilustrar un bucle con un contador decreciente, reescribiremos la
     función @c{triangulo} para que el contador disminuya a cero.

#      This is the reverse of the earlier version of the function. In this
#      case, to find out how many pebbles are needed to make a triangle with 3
#      rows, add the number of pebbles in the third row, 3, to the number in
#      the preceding row, 2, and then add the total of those two rows to the
#      row that precedes them, which is 1.
     Esto es lo inverso de la versión anterior de la función. En este caso, para
     saber cuantos guijarros se necesitan para crear un triángulo con 3 filas,
     se suma el número de guijarros en la tercera fila, 3, al numero en la fila
     anterior, 2, y luego se suman el total de esas dos filas a la fila que lo
     precede, que es 1.

#      Likewise, to find the number of pebbles in a triangle with 7 rows, add
#      the number of pebbles in the seventh row, 7, to the number in the
#      preceding row, which is 6, and then add the total of those two rows to
#      the row that precedes them, which is 5, and so on. As in the previous
#      example, each addition only involves adding two numbers, the total of
#      the rows already added up and the number of pebbles in the row that is
#      being added to the total. This process of adding two numbers is
#      repeated again and again until there are no more pebbles to add.
     Del mismo modo, para encontrar el número de guijarros en un triángulo con 7
     filas, se suma el número de guijarros en la septima fila, 7, al número en la
     fila anterior, que es 6, y luego se suma el total de estas dos filas a la
     fila que las precede, que es 5, y así sucesivamente. Como en el ejemplo
     anterior, cada suma solo implica sumar dos números, el total de las filas ya
     sumadas y el número de guijarros en la fila que se suma al total. Este
     proceso de sumar dos números se repite una y otra vez hasta que no haya más
     guijarros que agregar.

#      We know how many pebbles to start with: the number of pebbles in the
#      last row is equal to the number of rows. If the triangle has seven
#      rows, the number of pebbles in the last row is 7. Likewise, we know how
#      many pebbles are in the preceding row: it is one less than the number in
#      the row.
     Sabemos con cuántos guijarros empezar: el número de guijarros en la última
     fila es igual al número de filas. Si el triángulo tiene siete filas, el
     número de guijarros en la última fila es 7. Del mismo modo, sabemos cuántos
     guijarros hay en la fila anterior: uno menos que el número en la fila
     actual.

# **** The parts of the function definition
**** Las partes de la definición de función

#      We start with three variables: the total number of rows in the triangle;
#      the number of pebbles in a row; and the total number of pebbles, which
#      is what we want to calculate. These variables can be named
#      @c{number-of-rows}, @c{number-of-pebbles-in-row}, and @c{total},
#      respectively.
     Empezamos con tres variables: el número total de filas en el triángulo; el
     número de guijarros en una fila; y el número total de guijarros, que es lo
     que queremos calcular. Estas variables pueden llamarse @c{numero-de-filas},
     @c{numero-de-guijarros-en-fila}, y @c{total}, respectivamente.

#      Both @c{total} and @c{number-of-pebbles-in-row} are used only inside the
#      function and are declared with @c{let}. The initial value of @c{total}
#      should, of course, be zero. However, the initial value of
#      @c{number-of-pebbles-in-row} should be equal to the number of rows in
#      the triangle, since the addition will start with the longest row.
     Tanto @c{total} como @c{numero-de-guijarros-en-fila} se usan solo dentro de
     la función y se declaran con @c{let}. El valor inicial de @c{total} deberia
     ser cero. Sin embargo, el valor inicial de @c{numero-de-guijarros-en-fila}
     deberia ser igual al número de filas en el triángulo, ya que la suma
     comenzara con la fila más larga.

#      This means that the beginning of the @c{let} expression will look like
#      this:
     Esto significa que el principio de la expresión @c{let} se verá así:

#      ..src > elisp
#        (let ((total 0)
#              (number-of-pebbles-in-row number-of-rows))
#          body…)
#      < src..
     ..src > elisp
       (let ((total 0)
             (numero-de-guijarros-en-fila numero-de-filas))
         cuerpo…)
     < src..

#      The total number of pebbles can be found by repeatedly adding the number
#      of pebbles in a row to the total already found, that is, by repeatedly
#      evaluating the following expression:
     El número total de guijarros se puede encontrar sumando repetidamente
     el número de guijarros en una fila al total ya encontrado, es decir,
     evaluando repetidamente la siguiente expresión:

#      ..src > elisp
#        (setq total (+ total number-of-pebbles-in-row))
#      < src..
     ..src > elisp
       (setq total (+ total numero-de-guijarros-en-fila))
     < src..

#      After the @c{number-of-pebbles-in-row} is added to the @c{total}, the
#      @c{number-of-pebbles-in-row} should be decremented by one, since the
#      next time the loop repeats, the preceding row will be added to the
#      total.
     Después de sumar @c{numero-de-guijarros-en-fila} al @c{total}, el
     @c{numero-de-guijarros-en-fila} debe decrecer por uno, ya que la siguiente
     vez que el bucle se repita, la fila anterior se sumara al total.

#      The number of pebbles in a preceding row is one less than the number of
#      pebbles in a row, so the built-in Emacs Lisp function @c{1-} can be used
#      to compute the number of pebbles in the preceding row. This can be done
#      with the following expression:
     El número de guijarros en una fila anterior es uno menos que el número de
     guijarros en la fila actual, por lo que se utilizara la función nativa
     @c{1-} de Emacs para calcular el número de guijarros de la fila
     anterior. Esto se puede hacer con la siguiente expresión:

#      ..src > elisp
#        (setq number-of-pebbles-in-row
#              (1- number-of-pebbles-in-row))
#      < src..
     ..src > elisp
       (setq numero-de-guijarros-en-fila
             (1- numero-de-guijarros-en-fila))
     < src..

#      Finally, we know that the @c{while} loop should stop making repeated
#      additions when there are no pebbles in a row. So the test for the
#      @c{while} loop is simply:
     Finalmente, sabemos que el bucle @c{while} deberia detenerse cuando no
     halla guijarros en una fila. Así que la prueba en el bucle @c{while} es
     simple:

#      ..src > elisp
#        (while (> number-of-pebbles-in-row 0)
#      < src..
     ..src > elisp
       (while (> numero-de-guijarros-en-fila 0)
     < src..

# **** Putting the function definition together
**** Juntando la definición de función

#      We can put these expressions together to create a function definition
#      that works. However, on examination, we find that one of the local
#      variables is unneeded!
     Podemos juntar estas expresiones para crear una definición de función que
     funcione. Sin embargo, al examinarlas, encontraremos que una de las
     variables locales ¡es innecesaria!

#      The function definition looks like this:
     La definición de función tiene este aspeto:

#      ..src > elisp
#        ;;; First subtractive version.
#        (defun triangle (number-of-rows)
#          "Add up the number of pebbles in a triangle."
#          (let ((total 0)
#                (number-of-pebbles-in-row number-of-rows))
#            (while (> number-of-pebbles-in-row 0)
#              (setq total (+ total number-of-pebbles-in-row))
#              (setq number-of-pebbles-in-row
#                    (1- number-of-pebbles-in-row)))
#            total))
#      < src..
     ..src > elisp
       ;;; Primer version decreciente.
       (defun triangulo (numero-de-filas)
         "Suma el número de guijarros en un triángulo."
         (let ((total 0)
               (numero-de-guijarros-en-fila numero-de-filas))
           (while (> numero-de-guijarros-en-fila 0)
             (setq total (+ total numero-de-guijarros-en-fila))
             (setq numero-de-guijarros-en-fila
                   (1- numero-de-guijarros-en-fila)))
           total))
     < src..

#      As written, this function works.
     Como esta escrita, esta función funciona.

#      However, we do not need @c{number-of-pebbles-in-row}.
     Sin embargo, no se necesita @c{numero-de-guijarros-en-fila}.

#      When the @c{triangle} function is evaluated, the symbol
#      @c{number-of-rows} will be bound to a number, giving it an initial
#      value. That number can be changed in the body of the function as if it
#      were a local variable, without any fear that such a change will effect
#      the value of the variable outside of the function. This is a very
#      useful characteristic of Lisp; it means that the variable
#      @c{number-of-rows} can be used anywhere in the function where
#      @c{number-of-pebbles-in-row} is used.
     Cuando se evalua la función @c{triangulo}, el símbolo @c{numero-de-filas} se
     vinculara a un número, dandole un valor inicial. Ese número puede ser
     modificado en el cuerpo de la función como si fuera una variable local, sin
     temor a que tal cambio afecte el valor de la variable fuera de la
     función. Esta es una característica muy útil de Lisp; significa que la
     variable @c{numero-de-filas} se puede utilizar en cualquier lugar de la
     función donde se utilice @c{numero-de-guijarros-en-fila}.

#      Here is a second version of the function written a bit more cleanly:
     Aquí hay una segunda versión de la función escrita un poco más
     limpiamente:

#      ..src > elisp
#        (defun triangle (number)                ; Second version.
#          "Return sum of numbers 1 through NUMBER inclusive."
#          (let ((total 0))
#            (while (> number 0)
#              (setq total (+ total number))
#              (setq number (1- number)))
#            total))
#      < src..
     ..src > elisp
       (defun triangulo (numero)                ; Segunda versión.
         "Devuelve la suma de números desde el 1 hasta e incluyendo a NUMERO."
         (let ((total 0))
           (while (> numero 0)
             (setq total (+ total numero))
             (setq numero (1- numero)))
           total))
     < src..

#      In brief, a properly written @c{while} loop will consist of three parts:
     En resumen, un bucle @c{while} escrito apropiadamente constará de tres
     partes:

#      1. A test that will return false after the loop has repeated itself the
#         correct number of times.
     1. Una prueba que devuelva falso después de que el bucle se ha repetido el
        número de veces correcto.

#      2. An expression the evaluation of which will return the value desired
#         after being repeatedly evaluated.
     2. Una expresión cuya evaluación repetida devuelva el valor deseado.

#      3. An expression to change the value passed to the true-or-false-test so
#         that the test returns false after the loop has repeated itself the
#         right number of times.
     3. Una expresión para cambiar el valor pasado a la prueba-verdadero-o-falso
        para que esta devuelva falso después de que el bucle se haya repetido el
        numero de veces correcto.

# ** Save your time: @c{dolist} and @c{dotimes}
** Ahorra tu tiempo: @c{dolist} y @c{dotimes}

#    In addition to @c{while}, both @c{dolist} and @c{dotimes} provide for
#    looping. Sometimes these are quicker to write than the equivalent
#    @c{while} loop. Both are Lisp macros.  (See Section @l{elisp.html#Macros<>Macros}
#    in @e{The GNU Emacs Lisp Reference Manual}. )
   Además de @c{while}, tanto @c{dolist} como @c{dotimes} permiten hacer
   bucles. Algunas veces estos son mas rápidos de escribir que el bucle @c{while}
   equivalente. Ambas son macros Lisp. (Consulta la Seccion
   @l{elisp.html#Macros<>Macros} en @e(El Manual de Referencia GNU Emacs Lisp).)

#    @c{dolist} works like a @c{while} loop that ‘@c{cdr}s down a list’:
#    @c{dolist} automatically shortens the list each time it loops––takes the
#    @c{cdr} of the list––and binds the @c{car} of each shorter version of
#    the list to the first of its arguments.
   @c{dolist} funciona como un bucle @c{while} con ‘@c{cdr}s que acortan la
   lista’: @c{dolist} acorta automáticamente la lista con cada bucle––toma el @c{cdr} de
   la lista––y liga el @c{car} de cada versión mas corta al primero de sus
   argumentos.

#    @c{dotimes} loops a specific number of times: you specify the number.
   @c{dotimes} repite el bucle un número específico de veces: tu especificas el
   número.

# *** The @c{dolist} Macro
*** La macro @c{dolist}

#     Suppose, for example, you want to reverse a list, so that “first”
#     “second” “third” becomes “third” “second” “first”.
    Supón, por ejemplo, que quieres invertir una lista, para que “primero”,
    “segundo”, “tercero” se convierta en “tercero”, “segundo”, “primero”.

#     In practice, you would use the @c{reverse} function, like this:
    En la práctica, usarías la función @c{reverse}, como aqui:

#     ..src > elisp
    ..src > elisp
#       (setq animals '(gazelle giraffe lion tiger))
      (setq animales '(gacela jirafa leon tigre))

#       (reverse animals)
      (reverse animales)
#     < src..
    < src..

#     Here is how you could reverse the list using a @c{while} loop:
    A continuacion se muestra como se podría invertir la lista usando un bucle
    @c{while}:

#     ..src > elisp
    ..src > elisp
#       (setq animals '(gazelle giraffe lion tiger))
      (setq animales '(gacela jirafa leon tigre))

#       (defun reverse-list-with-while (list)
#         "Using while, reverse the order of LIST."
#         (let (value)  ; make sure list starts empty
#           (while list
#             (setq value (cons (car list) value))
#             (setq list (cdr list)))
#           value))
      (defun invertir-lista-con-while (lista)
        "Usando while, invierte el orden de LISTA."
        (let (valor)  ; asegura que la lista comienza vacía
          (while lista
            (setq valor (cons (car lista) valor))
            (setq lista (cdr lista)))
          valor))

#       (reverse-list-with-while animals)
      (invertir-lista-con-while animales)
#     < src..
    < src..

#     And here is how you could use the @c{dolist} macro:
    Y aquí se ve cómo puedes usar la macro @c{dolist}:

#     ..src > elisp
    ..src > elisp
#       (setq animals '(gazelle giraffe lion tiger))
      (setq animales '(gacela jirafa leon tigre))

#       (defun reverse-list-with-dolist (list)
#         "Using dolist, reverse the order of LIST."
#         (let (value)  ; make sure list starts empty
#           (dolist (element list value)
#             (setq value (cons element value)))))
      (defun invertir-lista-con-dolist (lista)
        "Usando dolist, invierte el orden de LISTA."
        (let (valor)  ; asegura que la lista empieza vacía
          (dolist (elemento lista valor)
            (setq valor (cons elemento valor)))))

#       (reverse-list-with-dolist animals)
      (invertir-lista-con-dolist animales)
#     < src..
    < src..

#     In Info, you can place your cursor after the closing parenthesis of each
#     expression and type @k{C-x C-e}; in each case, you should see
    Puedes colocar el cursor después del parentesis de cierre de
    cada expresión y pulsar @k{C-x C-e}; en cualquier caso, deberias ver

#     ..src > elisp
#       (tiger lion giraffe gazelle)
#     < src..
    ..src > elisp
      (tigre leon jirafa gacela)
    < src..

#     in the echo area.
    en el área de eco.

#     For this example, the existing @c{reverse} function is obviously best.
#     The @c{while} loop is just like our first example (see Section @l{#A
#     @c{while} Loop and a List}). The @c{while} first checks whether the list
#     has elements; if so, it constructs a new list by adding the first element
#     of the list to the existing list (which in the first iteration of the
#     loop is @c{nil}). Since the second element is prepended in front of the
#     first element, and the third element is prepended in front of the second
#     element, the list is reversed.
    Para este ejemplo, la función @c{reverse} obviamente es la mejor opcion. El
    bucle @c{while} es como nuestro primer ejemplo (Consulta la Seccion @l{#Un bucle
    @c{while} y una lista}). @c{while} comprueba si la lista tiene elementos; si
    es así, construye una nueva lista añadiendo el primer elemento de la lista a
    la lista existente (que en la primer iteración del bucle es @c{nil}). Puesto
    que el segundo elemento se asigna delante del primero, y el tercero delante
    del segundo, la lista se invierte.

#     In the expression using a @c{while} loop, the @c{(setq list (cdr list))}
#     expression shortens the list, so the @c{while} loop eventually stops. In
#     addition, it provides the @c{cons} expression with a new first element by
#     creating a new and shorter list at each repetition of the loop.
    En la expresión que usa un bucle @c{while}, la expresión @c{(setq lista (cdr
    lista))} acorta la lista, por lo que el bucle @c{while} termina
    deteniendose. Además, se proporciona la expresión @c{cons} con un nuevo
    primer elemento creando una nueva lista en cada repetición del bucle.

#     The @c{dolist} expression does very much the same as the @c{while}
#     expression, except that the @c{dolist} macro does some of the work you
#     have to do when writing a @c{while} expression.
    La expresión @c{dolist} hace lo mismo que la expresión @c{while}, excepto
    que la macro @c{dolist} hace algo del trabajo que tienes que hacer cuando se
    escribe una expresión @c{while}.

#     Like a @c{while} loop, a @c{dolist} loops. What is different is that it
#     automatically shortens the list each time it loops––it ‘@c{cdr}s down
#     the list’ on its own––and it automatically binds the @c{car} of each
#     shorter version of the list to the first of its arguments.
    Como un bucle @c{while}, @c{dolist} hace un bucle. Lo que es diferente es
    que @%c(dolist) acorta automáticamente la lista con cada repeticion––con
    ‘@c{cdr}s que reducen la lista’ por su cuenta––y asocia automáticamente el
    @c{car} de cada versión acortada de la lista al primero de sus argumentos.

#     In the example, the @c{car} of each shorter version of the list is
#     referred to using the symbol @'{element}, the list itself is called
#     @'{list}, and the value returned is called @'{value}. The remainder of
#     the @c{dolist} expression is the body.
    En el ejemplo, el @c{car} de cada versión reducida de la lista se vincula al
    símbolo @'{elemento}, la lista en sí se llama @'{lista}, y el valor devuelto
    se llama @'{valor}. El resto de la expresión @c{dolist} es el cuerpo.

#     The @c{dolist} expression binds the @c{car} of each shorter version of
#     the list to @c{element} and then evaluates the body of the expression;
#     and repeats the loop. The result is returned in @c{value}.
    La expresión @c{dolist} asocia el @c{car} de cada versión reducida de la
    lista a @c{elemento} y luego evalúa el cuerpo de la expresión y repite
    el bucle. El resultado es devuelto en @c{valor}.

# *** The @c{dotimes} Macro
*** La macro @c{dotimes}

#     The @c{dotimes} macro is similar to @c{dolist}, except that it loops a
#     specific number of times.
    La macro @c{dotimes} es similar a @c{dolist}, excepto que el bucle se
    repite un número específico de veces.

#     The first argument to @c{dotimes} is assigned the numbers 0, 1, 2 and so
#     forth each time around the loop, and the value of the third argument is
#     returned. You need to provide the value of the second argument, which is
#     how many times the macro loops.
    Al primer argumento de @c{dotimes} se le asignan los números 0, 1, 2 y así
    sucesivamente cada iteracion, y se devuelve el valor del tercer argumento.
    Se necesita proveer el valor del segundo argumento, que es el numero de
    veces que la macro se repite.

#     For example, the following binds the numbers from 0 up to, but not
#     including, the number 3 to the first argument, @c{number}, and then
#     constructs a list of the three numbers.  (The first number is 0, the
#     second number is 1, and the third number is 2; this makes a total of
#     three numbers in all, starting with zero as the first number.)
    Por ejemplo, lo siguiente asocia al primer argumento @c(numero) los números
    de 0 en adelante, pero no incluye, el número 3, y luego construye una lista
    de los tres números. (El primer número es 0, el segundo es 1, y el tercero es
    2; esto hace un total de tres, comenzando con cero como el primer número.)

#     ..srci > elisp
#       > (let (value)      ; otherwise a value is a void variable
#       ^   (dotimes (number 3 value)
#       ^     (setq value (cons number value))))
#       (2 1 0)
#     < srci..
    ..srci > elisp
      > (let (valor)      ; de otro modo, "valor" es una variable vacia
      ^   (dotimes (numero 3 valor)
      ^     (setq valor (cons numero valor))))
      (2 1 0)
    < srci..

#     @c{dotimes} returns @c{value}, so the way to use @c{dotimes} is to
#     operate on some expression @c(number) number of times and then return the
#     result, either as a list or an atom.
    @c{dotimes} devuelve @c{valor}, así que la forma de usar @c{dotimes} es
    operar sobre alguna expresión @c(numero) un numero de veces y luego devolver el
    resultado, como una lista o un átomo.

#     Here is an example of a @c{defun} that uses @c{dotimes} to add up the
#     number of pebbles in a triangle.
    Aquí hay un ejemplo de un @c{defun} que usa @c{dotimes} para sumar el número
    de guijarros en un triángulo.

#     ..src > elisp
    ..src > elisp
#       (defun triangle-using-dotimes (number-of-rows)
      (defun triangulo-utilizando-dotimes (numero-de-filas)
#         "Using dotimes, add up the number of pebbles in a triangle."
        "Usando dotimes, suma el número de guijarros en un triángulo."
#       (let ((total 0))  ; otherwise a total is a void variable
      (let ((total 0))  ; de otro modo total es una variable vacía
#         (dotimes (number number-of-rows total)
#           (setq total (+ total (1+ number))))))
        (dotimes (numero numero-de-filas total)
          (setq total (+ total (1+ numero))))))

#       (triangle-using-dotimes 4)
      (triangulo-utilizando-dotimes 4)
#     < src..
    < src..

# ** Recursion
** Recursividad

#    A recursive function contains code that tells the Lisp interpreter to call
#    a program that runs exactly like itself, but with slightly different
#    arguments. The code runs exactly the same because it has the same name.
#    However, even though the program has the same name, it is not the same
#    entity. It is different. In the jargon, it is a different ‘instance’.
   Una función recursiva contiene código que indica al intérprete Lisp que llame
   a un programa que se ejecuta exactamente como el, pero con argumentos
   ligeramente diferentes. El código funciona exactamente igual porque tiene el
   mismo nombre. Sin embargo, aunque el programa tenga el mismo nombre, no es la
   misma entidad. Eso diferente. En la jerga, se dice es una ‘instancia’
   diferente.

#    Eventually, if the program is written correctly, the ‘slightly different
#    arguments’ will become sufficiently different from the first arguments
#    that the final instance will stop.
   Eventualmente, si el programa se escribe correctamente, los ‘argumentos
   ligeramente diferentes’ llegan a ser suficientemente diferentes de los
   primeros argumentos para que la instancia final se detenga.

# *** Building Robots: Extending the Metaphor
*** Construyendo robots: Extendiendo la metáfora

#     It is sometimes helpful to think of a running program as a robot that
#     does a job. In doing its job, a recursive function calls on a second
#     robot to help it. The second robot is identical to the first in every
#     way, except that the second robot helps the first and has been passed
#     different arguments than the first.
    Algunas veces es útil pensar en un programa en ejecución como un robot que
    hace un trabajo. Al hacer su trabajo, una función recursiva llama a un
    segundo robot para que le ayude. El segundo robot es idéntico al primero en
    todos los sentidos, excepto que el segundo robot ayuda al primero y ha
    recibido argumentos diferentes al primero.

#     In a recursive function, the second robot may call a third; and the third
#     may call a fourth, and so on. Each of these is a different entity; but
#     all are clones.
    En una función recursiva, el segundo robot puede llamar a un tercero; y el
    tercero puede llamar a un cuarto, y así sucesivamente. Cada uno de ellos es
    una entidad diferente; pero todos son clones.

#     Since each robot has slightly different instructions––the arguments will
#     differ from one robot to the next––the last robot should know when to
#     stop.
    Dado que cada robot tiene instrucciones ligeramente diferentes––los
    argumentos difieren de un robot a otro––el último robot deberia saber cuando
    detenerse.

#     Let's expand on the metaphor in which a computer program is a robot.
    Expandamos la metáfora en la que un programa de ordenador es un robot.

#     A function definition provides the blueprints for a robot. When you
#     install a function definition, that is, when you evaluate a @c{defun}
#     special form, you install the necessary equipment to build robots. It is
#     as if you were in a factory, setting up an assembly line. Robots with
#     the same name are built according to the same blueprints. So they have,
#     as it were, the same ‘model number’, but a different ‘serial number’.
    Una definición de función proporciona los planos de un robot. Cuando se
    instala una definición de función, que es, cuando se evalúa una forma
    especial @c{defun}, se instala el equipo necesario para construir robots. Es
    como si estuvieras en una fábrica, construyendo una línea de montaje. Los
    robots con el mismo nombre se construyen segun los mismos planos. Así que
    tienen, por asi decirlo, el mismo ‘número de modelo’, pero un ‘número de
    serie’ diferente.

#     We often say that a recursive function ‘calls itself’. What we mean is
#     that the instructions in a recursive function cause the Lisp interpreter
#     to run a different function that has the same name and does the same job
#     as the first, but with different arguments.
    A menudo decimos que una función recursiva ‘se llama así misma’. Lo que
    queremos decir es que las instrucciones en una función recursiva hacen que
    el intérprete Lisp ejecute una función diferente que tiene el mismo nombre y
    hace el mismo trabajo que la primera, pero con argumentos diferentes.

#     It is important that the arguments differ from one instance to the next;
#     otherwise, the process will never stop.
    Es importante que los argumentos difieran de una instancia a la siguiente;
    de otro modo, el proceso nunca se detendra.

# *** The Parts of a Recursive Definition
*** Las partes de una definición recursiva

#     A recursive function typically contains a conditional expression which
#     has three parts:
    Una función recursiva típicamente contiene una expresión condicional que
    tiene tres partes:

#     1. A true-or-false-test that determines whether the function is called
#        again, here called the @:{do-again-test}.
    1. Una prueva-verdadero-o-falso que determina si la función se vuelve a llamar,
       aquí se llamara @:{prueba-hazlo-de-nuevo}.

#     2. The name of the function. When this name is called, a new instance of
#        the function––a new robot, as it were––is created and told what to do.
    2. El nombre de la función. Cuando este nombre se llama, se crea una nueva
       instancia de la función––un nuevo robot, por asi decirlo––y se le dice qué
       hacer.

#     3. An expression that returns a different value each time the function is
#        called, here called the @:{next-step-expression}. Consequently, the
#        argument (or arguments) passed to the new instance of the function
#        will be different from that passed to the previous instance. This
#        causes the conditional expression, the @:{do-again-test}, to test
#        false after the correct number of repetitions.
    3. Una expresión que devuelve un valor diferente cada vez que se llama a la
       función, aquí se llamara @:{expresion-del-siguiente-paso}.
       Consecuentemente, el argumento (o argumentos) pasados a la nueva
       instancia de la función será diferente del argumento (o argumentos)
       pasados a la instancia previa. Esto hace que la expresión condicional, la
       @:{prueba-hazlo-de-nuevo}, devuelva falso después del número correcto de
       repeticiones.


#     Recursive functions can be much simpler than any other kind of function.
#     Indeed, when people first start to use them, they often look so
#     mysteriously simple as to be incomprehensible. Like riding a bicycle,
#     reading a recursive function definition takes a certain knack which is
#     hard at first but then seems simple.
    Las funciones recursivas pueden ser mucho más simples que cualquier otro
    tipo de funcion. De hecho, cuando las personas comienzan a usarlas, con
    frecuencia parecen tan misteriosamente simples que resultan incomprensibles.
    Al igual que montar en bicicleta, leer la definicion de una función
    recursiva requiere una cierta habilidad, es dificil al principio, pero
    después parece facil.

#     There are several different common recursive patterns. A very simple
#     pattern looks like this:
    Hay varios patrones recursivos diferentes. Un patrón muy simple se ve asi:

#     ..src > elisp
#       (defun name-of-recursive-function (argument-list)
#         "documentation…"
#         (if do-again-test
#           body…
#           (name-of-recursive-function next-step-expression)))
#     < src..
    ..src > elisp
      (defun nombre-de-funcion-recursiva (lista-de-argumentos)
        "documentation…"
        (if prueba-hazlo-de-nuevo
          cuerpo…
          (nombre-de-funcion-recursiva expresion-del-siguiente-paso)))
    < src..

#     Each time a recursive function is evaluated, a new instance of it is
#     created and told what to do. The arguments tell the instance what to do.
    Cada vez que se evalua una función recursiva, se crea una nueva instancia y
    se le dice qué hacer. Los argumentos indican a la instancia qué hacer.

#     An argument is bound to the value of the next-step-expression. Each
#     instance runs with a different value of the next-step-expression.
    Un argumento es ligado al valor de la expresion-del-siguiente-paso. Cada
    instancia se ejecuta con un valor de la expresion-del-siguiente-paso
    diferente.

#     The value in the next-step-expression is used in the do-again-test.
    El valor en la expresion-del-siguiente-paso se utiliza en la
    prueba-hazlo-de-nuevo.

#     The value returned by the next-step-expression is passed to the new
#     instance of the function, which evaluates it (or some transmogrification
#     of it) to determine whether to continue or stop. The
#     next-step-expression is designed so that the do-again-test returns false
#     when the function should no longer be repeated.
    El valor devuelto por la expresion-del-siguiente-paso se pasa a la nueva
    instancia de la función, que lo evalúa para determinar si continua o se
    detiene. La expresion-del-siguiente-paso está diseñada para que la
    prueba-hazlo-de-nuevo devuelva falso cuando la función ya no deba repetirse.

#     The do-again-test is sometimes called the @:{stop condition}, since it
#     stops the repetitions when it tests false.
    La prueba-hazlo-de-nuevo a veces se denomina @:{condición de parada}, ya que
    detiene las repeticiones cuando la prueba falla.

# *** Recursion with a List
*** Recursividad con una lista

#     The example of a @c{while} loop that printed the elements of a list of
#     numbers can be written recursively. Here is the code, including an
#     expression to set the value of the variable @c{animals} to a list.
    El ejemplo de un bucle @c{while} que imprimia los elementos de una lista
    de números puede escribirse recursivamente. Aquí está el código,
    incluyendo una expresión para asignar el valor de la variable
    @c{animales} a una lista.

#     If you are reading this in Info in Emacs, you can evaluate this
#     expression directly in Info. Otherwise, you must copy the example to the
#     @f{*scratch*} buffer and evaluate each expression there. Use @k{C-u C-x
#     C-e} to evaluate the @c{(print-elements-recursively animals)} expression
#     so that the results are printed in the buffer; otherwise the Lisp
#     interpreter will try to squeeze the results into the one line of the echo
#     area.
    Si estás leyendo esto dentro de Emacs, puedes evaluar la expresión
    directamente. De lo contrario, debes copiar el ejemplo al búfer
    @f{*scratch*} y evalúar cada expresión alli. Utiliza @k{C-u C-x C-e} para
    evaluar la expresión @c{(imprimir-elementos-recursivamente animales)} de
    manera que se imprima el resultado en el búfer; de otro modo el intérprete
    Lisp intentara comprimir los resultados en la unica línea del área de eco.

#     Also, place your cursor immediately after the last closing parenthesis of
#     the @c{print-elements-recursively} function, before the comment.
#     Otherwise, the Lisp interpreter will try to evaluate the comment.
    También, coloca el  cursor inmediatamente después del último paréntesis
    de cierre de la función @c{imprimir-elementos-recursivamente}, antes del
    comentario. De lo contrario, el intérprete Lisp intentará evaluar el
    comentario.

#     ..src > elisp
    ..src > elisp
#       (setq animals '(gazelle giraffe lion tiger))
      (setq animales '(gacela jirafa leon tigre))

#       (defun print-elements-recursively (list)
#         "Print each element of LIST on a line of its own.
#       Uses recursion."
#         (when list                            ; do-again-test
#               (print (car list))              ; body
#               (print-elements-recursively     ; recursive call
#                (cdr list))))                  ; next-step-expression
      (defun imprimir-elementos-recursivamente (lista)
        "Imprime cada elemento de LISTA en una línea propia.
      Usa recursión."
        (when lista                               ; prueba-hazlo-de-nuevo
              (print (car lista))                 ; cuerpo
              (imprimir-elementos-recursivamente  ; llamada recursiva
               (cdr lista))))                     ; expresion-del-siguiente-paso

#       (print-elements-recursively animals)
      (imprimir-elementos-recursivamente animales)
#     < src..
    < src..

#     The @c{print-elements-recursively} function first tests whether there is
#     any content in the list; if there is, the function prints the first
#     element of the list, the @c{car} of the list. Then the function
#     ‘invokes itself’, but gives itself as its argument, not the whole list,
#     but the second and subsequent elements of the list, the @c{cdr} of the
#     list.
    La función @c{imprimir-elementos-recursivamente} primero prueba si hay algun
    contenido en la lista; si lo hay, la función imprime el primer elemento de
    la lista, el @c{car} de la lista. Entonces la función se ‘invoca a sí
    misma’, pero se da como argumento, no la lista completa, sino el segundo
    y subsiguientes elementos de esta, es decir, el @c{cdr} de la lista.

#     Put another way, if the list is not empty, the function invokes another
#     instance of code that is similar to the initial code, but is a different
#     thread of execution, with different arguments than the first instance.
    Dicho de otro modo, si la lista no está vacía, la función invoca otra
    instancia de código que es similar al código inicial, pero es un hilo
    de ejecución diferente, con argumentos diferentes o los de la primera instancia.

#     Put in yet another way, if the list is not empty, the first robot
#     assembles a second robot and tells it what to do; the second robot is a
#     different individual from the first, but is the same model.
    Dicho de otra manera mas, si la lista no está vacía, el primer robot ensambla
    un segundo robot y le dice qué hacer; el segundo robot es un individuo
    diferente del primero, pero es del mismo modelo.

#     When the second evaluation occurs, the @c{when} expression is evaluated
#     and if true, prints the first element of the list it receives as its
#     argument (which is the second element of the original list). Then the
#     function ‘calls itself’ with the @c{cdr} of the list it is invoked with,
#     which (the second time around) is the @c{cdr} of the @c{cdr} of the
#     original list.
    Cuando se produce la segunda evaluación, se evalua la expresión @c{when} y
    si es verdadera, imprime el primer elemento de la lista que recibe como
    argumento (que es el segundo elemento de la lista original). A continuacion
    la función ‘se llama a sí misma’ (la segunda vez) con el @c{cdr} del @c{cdr}
    de la lista original.

#     Note that although we say that the function ‘calls itself’, what we mean
#     is that the Lisp interpreter assembles and instructs a new instance of
#     the program. The new instance is a clone of the first, but is a separate
#     individual.
    Ten en cuenta que aunque decimos que la función ‘se llama a sí misma’, lo
    que queremos decir es que el intérprete Lisp ensambla e instruye una nueva
    instancia del programa. La nueva instancia es un clon del primero, pero es
    un individuo separado.

#     Each time the function ‘invokes itself’, it invokes itself on a shorter
#     version of the original list. It creates a new instance that works on a
#     shorter list.
    Cada vez que la función ‘se invoca a sí misma’, se invoca con una versión
    mas corta de la lista original. Crea una nueva instancia que funciona en una
    lista mas corta.

#     Eventually, the function invokes itself on an empty list. It creates a
#     new instance whose argument is @c{nil}. The conditional expression tests
#     the value of @c{list}. Since the value of @c{list} is @c{nil}, the
#     @c{when} expression tests false so the then-part is not evaluated. The
#     function as a whole then returns @c{nil}.
    Eventualmente, la función se invoca a sí misma con una lista vacía. Crea una
    nueva instancia cuyo argumento es @c{nil}. La expresión condicional prueba
    el valor de @c{lista}. Ya que el valor de la @c{lista} es @c{nil}, la
    expresión @c{when} prueba falso por lo que la parte-then no se evalua. La
    función como un todo entonces devuelve @c{nil}.

#     When you evaluate the expression @c{(print-elements-recursively animals)}
#     in the @f{*scratch*} buffer, you see this result:
    Cuando se evalúa la expresión @c{(imprimir-elementos-recursivamente animales)} en
    el búfer @f{*scratch*}, se ve este resultado:

#     ..example >
    ..example >
#       gazelle
      gacela

#       giraffe
      jirafa

#       lion
      leon

#       tiger
      tigre
#       nil
      nil
#     < example..
    < example..

# *** Recursion in Place of a Counter
*** Recursión en lugar de un contador

#     The @c{triangle} function described in a previous section can also be
#     written recursively. It looks like this:
    La función @c{triangulo} descrita en una sección anterior tambien se puede
    escribir recursivamente. Se vera así:

#     ..src > elisp
    ..src > elisp
#       (defun triangle-recursively (number)
#         "Return the sum of the numbers 1 through NUMBER inclusive.
#       Uses recursion."
#         (if (= number 1)                    ; do-again-test
#             1                               ; then-part
#           (+ number                         ; else-part
#              (triangle-recursively          ; recursive call
#               (1- number)))))               ; next-step-expression
      (defun triangulo-recursivo (numero)
        "Devuelve la suma de números desde el 1 hasta e incluyendo a NUMERO.
      Usa recursion."
        (if (= numero 1)                    ; prueba-hazlo-de-nuevo
            1                               ; parte-then
          (+ numero                         ; parte-else
             (triangulo-recursivo           ; llamada recursiva
              (1- numero)))))               ; expresion-del-siguiente-paso

#       (triangle-recursively 7)
      (triangulo-recursivo 7)
#     < src..
    < src..

#     You can install this function by evaluating it and then try it by
#     evaluating @c{(triangle-recursively 7)}.  (Remember to put your cursor
#     immediately after the last parenthesis of the function definition, before
#     the comment.)  The function evaluates to 28.
    Puedes instalar esta función evaluandola y luego probarla evaluando
    @c{(triangulo-recursivo 7)}. (Recuerda colocar el cursor inmediatamente
    después del último paréntesis de la definición de la función, antes del
    comentario.) La función se evalúa a 28.

#     To understand how this function works, let's consider what happens in the
#     various cases when the function is passed 1, 2, 3, or 4 as the value of
#     its argument.
    Para comprender cómo funciona esta función, hay que considerar qué ocurre en
    varios casos cuando la función pasa 1, 2, 3, o 4 como el valor de su
    argumento.

#      First, what happens if the value of the argument is 1?
    Primero, ¿que sucede si el valor del argumento es 1?

#      The function has an @c{if} expression after the documentation string.
#      It tests whether the value of @c{number} is equal to 1; if so, Emacs
#      evaluates the then-part of the @c{if} expression, which returns the
#      number 1 as the value of the function.  (A triangle with one row has one
#      pebble in it.)
    La función tiene una expresión @c{if} después de la cadena de
    documentación. Prueba si el valor de @c{numero} es igual a 1; si es
    así, Emacs evalúa la parte-then de la expresión @c{if}, que devuelve el
    número 1 como el valor de la función. (Un triángulo con una fila tiene un
    guijarro dentro.)

#      Suppose, however, that the value of the argument is 2. In this case,
#      Emacs evaluates the else-part of the @c{if} expression.
    Supón, sin embargo, que el valor del argumento es 2. En este caso, Emacs
    evalúa la parte-else de la expresión @c{if}.

#      The else-part consists of an addition, the recursive call to
#      @c{triangle-recursively} and a decrementing action; and it looks like
#      this:
    La parte-else consiste en una suma, la llamada recursiva a
    @c{triangulo-recursivo} y una acción de decremento; y se ve así:

#      ..src > elisp
#        (+ number (triangle-recursively (1- number)))
#      < src..
    ..src > elisp
      (+ numero (triangulo-recursivo (1- numero)))
    < src..

#      When Emacs evaluates this expression, the innermost expression is
#      evaluated first; then the other parts in sequence. Here are the steps
#      in detail:
    Cuando Emacs evalúa esta expresión, la expresión interna se evalua
    primero; luego las otras partes en secuencia. Aquí están los pasos en
    detalle:

#      - Step 1 Evaluate the innermost expression.
    - Paso 1 Evalúar la expresión mas interna.

#        The innermost expression is @c{(1- number)} so Emacs decrements the
#        value of @c{number} from 2 to 1.
      La expresión mas interna es @c{(1- numero)} por lo que Emacs decrementa el valor
      de @c{numero} de 2 a 1.

#      - Step 2 Evaluate the @c{triangle-recursively} function.
    - Paso 2 Evalúar la función @c{triangulo-recursivo}.

#        The Lisp interpreter creates an individual instance of
#        @c{triangle-recursively}. It does not matter that this function is
#        contained within itself. Emacs passes the result Step 1 as the
#        argument used by this instance of the @c{triangle-recursively}
#        function
      El intérprete Lisp crea una instancia individual de @c{triangulo-recursivo}.
      No importa que esta función este contenida dentro de sí misma. Emacs pasa
      el resultado del Paso 1 como el argumento usado por esta instancia de la
      función @c{triangulo-recursivo}

#        In this case, Emacs evaluates @c{triangle-recursively} with an
#        argument of 1. This means that this evaluation of
#        @c{triangle-recursively} returns 1.
      En este caso, Emacs evalúa @c{triangulo-recursivo} con un argumento
      de 1. Esto significa que esta evaluación de @c{triangulo-recursivo}
      devuelve 1.

#      - Step 3 Evaluate the value of @c{number}.
    - Paso 3 Evalúar el valor de @c{numero}.

#        The variable @c{numero} is the second element of the list that starts
#        with @c{+}; its value is 2.
      La variable @c{numero} es el segundo elemento de la lista que empieza
      con @c{+}; su valor es 2.

#      - Step 4 Evaluate the @c{+} expression.
    - Paso 4 Evalúar la expresión @c{+}.

#        The @c{+} expression receives two arguments, the first from the
#        evaluation of @c{number} (Step 3) and the second from the evaluation
#        of @c{triangle-recursively} (Step 2).
      La expresión @c{+} recibe dos argumentos, el primero viene de la
      evaluación del @c{numero} (Paso 3) y el segundo de la evaluación de
      @c{triangulo-recursivo} (Paso 2).

#        The result of the addition is the sum of 2 plus 1, and the number 3 is
#        returned, which is correct. A triangle with two rows has three
#        pebbles in it.
      El resultado de la operacion es la suma de 2 + 1, y se devuelve el número
      3, que es correcto. Un triángulo con dos filas tiene tres guijarros.

# **** An argument of 3 or 4
**** Un argumento de 3 o 4

#      Suppose that @c{triangle-recursively} is called with an argument of 3.
     Supón que @c{triangulo-recursivo} se llama con un argumento de 3.

#      - Step 1 Evaluate the do-again-test.
     - Paso 1 Evalúa la prueba-hazlo-de-nuevo.

#        The @c{if} expression is evaluated first. This is the do-again-test
#        and returns false, so the else-part of the @c{if} expression is
#        evaluated.  (Note that in this example, the do-again-test causes the
#        function to call itself when it tests false, not when it tests true.)
       La expresión @c{if} se evalúa primero. Esto es la prueba-hazlo-de-nuevo y
       devuelve falso, así que se evalua la parte-else de la expresión
       @c{if}. (Ten en cuenta que en este ejemplo, la prueba-hazlo-de-nuevo
       hace que la función se llame a sí misma cuando la prueba es falsa, no
       cuando es verdadera.)

#      - Step 2 Evaluate the innermost expression of the else-part.
     - Paso 2 Evalúar la expresión mas interna de la parte-else.

#        The innermost expression of the else-part is evaluated, which
#        decrements 3 to 2. This is the next-step-expression.
       Se evalua la expresión mas interna de la parte-else, que decrementa 3
       a 2. Esta es la expresion-del-siguiente-paso.

#      - Step 3 Evaluate the @c{triangle-recursively} function.
     - Paso 3 Evalúar la función @c{triangulo-recursivo}.

#        The number 2 is passed to the @c{triangle-recursively} function.
       El número 2 se pasa a la función @c{triangulo-recursivo}.

#        We already know what happens when Emacs evaluates
#        @c{triangle-recursively} with an argument of 2. After going through
#        the sequence of actions described earlier, it returns a value of 3.
#        So that is what will happen here.
       Nosotros ya sabemos lo que ocurre cuando Emacs evalúa
       @c{triangulo-recursivo} con un argumento de 2. Después de pasar a través de
       la secuencia de acciones descritas anteriormente, devuelve un valor
       de 3. Así que eso es lo que ocurrirá aquí.

#      - Step 4 Evaluate the addition.
     - Paso 4 Evalúar la suma.

#        3 will be passed as an argument to the addition and will be added to
#        the number with which the function was called, which is 3.
       3 será pasado como argumento a la suma y se sumara al número con el que
       se ha llamado a la función, que es 3.


#      The value returned by the function as a whole will be 6.
     El valor devuelto por la función en su conjunto será 6.

#      Now that we know what will happen when @c{triangle-recursively} is
#      called with an argument of 3, it is evident what will happen if it is
#      called with an argument of 4:
     Ahora que sabemos qué ocurrirá cuando se llame a @c{triangulo-recursivo}
     con un argumento de 3, es evidente lo que ocurrirá si se llama con un
     argumento de 4:

#      ..tab >
     ..tab >
#        In the recursive call, the evaluation of
       En la llamada recursiva, la evaluación de

#        ..src > elisp
#          (triangle-recursively (1- 4))
#        < src..
       ..src > elisp
         (triangulo-recursivo (1- 4))
       < src..

#        will return the value of evaluating
       devolvera el valor de evaluar

#        ..src > elisp
#          (triangle-recursively 3)
#        < src..
       ..src > elisp
         (triangulo-recursivo 3)
       < src..

#        which is 6 and this value will be added to 4 by the addition in the
#        third line.
       que es 6 y este valor se sumara a 4 mediante la suma en la tercera
       línea.
#      < tab..
     < tab..


#      The value returned by the function as a whole will be 10.
     El valor devuelto por la función en su conjunto será 10.

#      Each time @c{triangle-recursively} is evaluated, it evaluates a version
#      of itself––a different instance of itself––with a smaller argument,
#      until the argument is small enough so that it does not evaluate itself.
     Cada vez que se evalua @c{triangulo-recursivo}, se evalua una
     versión de sí misma––una instancia diferente en sí––con un argumento
     mas pequeño, hasta que el argumento es lo suficientemente pequeño para que
     no se evalue a si misma.

#      Note that this particular design for a recursive function requires that
#      operations be deferred.
     Ten en cuenta que este particular diseño de una función recursiva
     requiere que las operaciones se pospongan.

#      Before @c{(triangle-recursively 7)} can calculate its answer, it must
#      call @c{(triangle-recursively 6)}; and before @c{(triangle-recursively
#      6)} can calculate its answer, it must call @c{(triangle-recursively 5)};
#      and so on. That is to say, the calculation that
#      @c{(triangle-recursively 7)} makes must be deferred until
#      @c{(triangle-recursively 6)} makes its calculation; and
#      @c{(triangle-recursively 6)} must defer until @c{(triangle-recursively
#      5)} completes; and so on.
     Antes de que @c{(triangulo-recursivo 7)} pueda calcular su respuesta, debe
     llamar a @c{(triangulo-recursivo 6)}; y antes de que
     @c{(triangulo-recursivo 6)} pueda calcular su respuesta debe llamar a
     @c{(triangulo-recursivo 5)}; y así sucesivamente. Es decir, el cálculo
     que hace @c{(triangulo-recursivo 7)} debe ser pospuesto hasta que
     @c{(triangulo-recursivo 6)} haga su cálculo; y @c{(triangulo-recursivo 6)}
     debe posponerse hasta que @c{(triangulo-recursivo 5)} se complete; y así
     sucesivamente.

#      If each of these instances of @c{triangle-recursively} are thought of as
#      different robots, the first robot must wait for the second to complete
#      its job, which must wait until the third completes, and so on.
     Si se piensa que cada una de estas instancias de @c{triangulo-recursivo}
     son robots diferentes, el primer robot debe esperar al segundo para
     completar su trabajo, que debe esperar hasta que el tercero se complete, y
     así sucesivamente.

#      There is a way around this kind of waiting, which we will discuss in
#      Section @l{#Recursion without Deferments}.
     Hay una forma de evitar este tipo de espera, que se discutirá en la Seccion
     @l{#Recursividad sin aplazamiento}.

# *** Recursion Example Using @c{cond}
*** Ejemplo de recursión usando @c{cond}

#     The version of @c{triangle-recursively} described earlier is written with
#     the @c{if} special form. It can also be written using another special
#     form called @c{cond}. The name of the special form @c{cond} is an
#     abbreviation of the word @'{conditional}.
    La versión de @c{triangulo-recursivo} descrita anteriormente se escribió con la
    forma especial @c{if}. También se puede escribir usando otra forma
    especial llamada @c{cond}. El nombre de la forma especial @c{cond} es una
    abreviación de la palabra @'{conditional} @%i(condicional).

#     Although the @c{cond} special form is not used as often in the Emacs Lisp
#     sources as @c{if}, it is used often enough to justify explaining it.
    Aunque la forma especial @c{cond} no se usa tan a menudo en las fuentes
    de Emacs como @c{if}, se usa con bastante frecuencia para justificar su
    explicacion.

#     The template for a @c{cond} expression looks like this:
    La plantilla de una expresión @c{cond} se ve asi:

#     ..src > elisp
#       (cond
#        body…)
#     < src..
    ..src > elisp
      (cond
       cuerpo…)
    < src..

#     where the @c{body} is a series of lists.
    donde el @c{cuerpo} es una serie de listas.

#     Written out more fully, the template looks like this:
    Escrito de forma más completa, la plantilla se ve asi:

#     ..src > elisp
#       (cond
#        (first-true-or-false-test first-consequent)
#        (second-true-or-false-test second-consequent)
#        (third-true-or-false-test third-consequent)
#         …)
#     < src..
    ..src > elisp
      (cond
       (primera-prueba-verdadero-o-falso primera-consequencia)
       (segunda-prueba-verdadero-o-falso segunda-consequencia)
       (tercera-prueba-verdadero-o-falso tercera-consequencia)
        …)
    < src..

#     When the Lisp interpreter evaluates the @c{cond} expression, it evaluates
#     the first element (the @c{car} or true-or-false-test) of the first
#     expression in a series of expressions within the body of the @c{cond}.
    Cuando el intérprete Lisp evalúa la expresión @c{cond}, evalúa el primer
    elemento (el @c{car} o prueba-verdadero-o-falso) de la primer expresión en
    una serie de expresiones dentro del cuerpo del @c{cond}.

#     If the true-or-false-test returns @c{nil} the rest of that expression,
#     the consequent, is skipped and the true-or-false-test of the next
#     expression is evaluated. When an expression is found whose
#     true-or-false-test returns a value that is not @c{nil}, the consequent of
#     that expression is evaluated. The consequent can be one or more
#     expressions. If the consequent consists of more than one expression, the
#     expressions are evaluated in sequence and the value of the last one is
#     returned. If the expression does not have a consequent, the value of the
#     true-or-false-test is returned.
    Si la prueba-verdadero-o-falso devuelve @c{nil} el resto de esa expresión,
    la consecuencia; se descarta y se evalua la prueba-verdadero-o-falso de la
    siguiente expresión.  Cuando se encuentra una expresión cuya
    prueba-verdadero-o-falso devuelve un valor que no es @c{nil}, se evalua la
    consecuencia de esa expresión. La consecuencia puede ser una o más expresiones. Si
    la consecuencia consiste de más de una expresión, las expresiones se evaluan en
    secuencia y se devuelve el valor de la última. Si la expresión no tiene
    consecuencia, se devuelve el valor de la prueba-verdadero-o-falso.

#     If none of the true-or-false-tests test true, the @c{cond} expression
#     returns @c{nil}.
    Si ninguna de las pruebas prueba-verdadero-o-falso es verdadera, la
    expresión @c{cond} devuelve @c{nil}.

#     Written using @c{cond}, the @c{triangle} function looks like this:
    Asi se ve la función @c{triangle}, usando @c{cond}:

#     ..src > elisp
#       (defun triangle-using-cond (number)
#         (cond ((<= number 0) 0)
#               ((= number 1) 1)
#               ((> number 1)
#                (+ number (triangle-using-cond (1- number))))))
#     < src..
    ..src > elisp
      (defun triangulo-usando-cond (numero)
        (cond ((<= numero 0) 0)
              ((= numero 1) 1)
              ((> numero 1)
               (+ numero (triangulo-usando-cond (1- numero))))))
    < src..

#     In this example, the @c{cond} returns 0 if the number is less than or
#     equal to 0, it returns 1 if the number is 1 and it evaluates @c{(+ number
#     (triangle-using-cond (1- number)))} if the number is greater than 1.
    En este ejemplo, @c{cond} devuelve 0 si el número es menor o igual a 0,
    devuelve 1 si el número es 1 y evalúa @c{(+ numero (triangulo-usando-cond
    (1- numero)))} si el número es mayor a 1.

# *** Recursive Patterns
*** Patrones recursivos

#     Here are three common recursive patterns. Each involves a list.
#     Recursion does not need to involve lists, but Lisp is designed for lists
#     and this provides a sense of its primal capabilities.
    Aquí hay tres patrones recursivos comunes. Cada uno implica una lista. La
    recursión no necesita involucrar listas, pero Lisp esta diseñado para listas
    y esto proporciona una idea de sus capacidades primarias.

# **** Recursive Pattern: @e{every}
**** Patrón recursivo: @e{every}

#      In the @c{every} recursive pattern, an action is performed on every
#      element of a list.
     En el patrón recursivo @c{every}, se desarrolla una acción en cada
     elemento de una lista.

#      The basic pattern is:
     El patrón básico es:

#      - If a list be empty, return @c{nil}.
     - Si una lista esta vacía, devuelve @c{nil}.

#      - Else, act on the beginning of the list (the @c{car} of the list)
     - Si no, actua al principio de la lista (el @c{car} de la lista)

#        + through a recursive call by the function on the rest (the @c{cdr})
#          of the list,
       + a través de una llamada recursiva por la función en el resto (el
         @c{cdr}) de la lista,

#        + and, optionally, combine the acted-on element, using @c{cons}, with
#          the results of acting on the rest.
       + y, opcionalmente, combina el elemento sobre el que actúa, usando
         @c{cons}, con los resultados de actuar sobre el resto.


#      Here is example:
     Aquí está el ejemplo:

#      ..src > elisp
#        (defun square-each (numbers-list)
#          "Square each of a NUMBERS LIST, recursively."
#          (if (not numbers-list)                ; do-again-test
#              nil
#            (cons
#             (* (car numbers-list) (car numbers-list))
#             (square-each (cdr numbers-list))))) ; next-step-expression
#      < src..
     ..src > elisp
       (defun cuadrar-cada-uno (lista-de-numeros)
         "El cuadrado de cada elemento en LISTA DE NUMEROS, recursivamente."
         (if (not lista-de-numeros)          ; prueba-hazlo-de-nuevo
             nil
           (cons
            (* (car lista-de-numeros) (car lista-de-numeros))
            (cuadrar-cada-uno (cdr lista-de-numeros))))) ; expresion-del-siguiente-paso
     < src..

#      ..srci > elisp
#        > (square-each '(1 2 3))
#        (1 4 9)
#      < srci..
     ..srci > elisp
       > (cuadrar-cada-uno '(1 2 3))
       (1 4 9)
     < srci..

#      If @c{numbers-list} is empty, do nothing. But if it has content,
#      construct a list combining the square of the first number in the list
#      with the result of the recursive call.
     Si @c{lista-de-numeros} está vacía, no hay que hacer nada. Pero si tiene
     contenido, se construye una lista combinando el cuadrado del primer
     número en la lista con el resultado de la llamada recursiva.

#      (The example follows the pattern exactly: @c{nil} is returned if the
#      numbers' list is empty. In practice, you would write the conditional so
#      it carries out the action when the numbers' list is not empty.)
     (El ejemplo sigue el patrón exactamente: se devuelve @c{nil} si la lista
     de números esta vacía. En la práctica, se escribiría el condicional para que
     lleve a cabo la acción cuando la lista de números no este vacía.)

#      The @c{print-elements-recursively} function (see Section @l{#Recursion
#      with a List}) is another example of an @c{every} pattern, except in this
#      case, rather than bring the results together using @c{cons}, we print
#      each element of output.
     La función @c{imprimir-elementos-recursivamente} (Ver Sección @l{#Recursividad
     con una Lista}) es otro ejemplo de un patrón @c{every}, excepto que en este
     caso, en vez de juntar los resultados usando @c{cons}, se imprime
     cada elemento de salida.

#      The @c{print-elements-recursively} function looks like this:
     La función @c{imprimir-elementos-recursivamente} se ve asi:

#      ..src > elisp
     ..src > elisp
#        (setq animals '(gazelle giraffe lion tiger))
       (setq animales '(gacela jirafa leon tigre))

#        (defun print-elements-recursively (list)
#          "Print each element of LIST on a line of its own.
#        Uses recursion."
#          (when list                            ; do-again-test
#                (print (car list))              ; body
#                (print-elements-recursively     ; recursive call
#                 (cdr list))))                  ; next-step-expression
       (defun imprimir-elementos-recursivamente (lista)
         "Imprime cada elemento de LISTA en una línea propia.
       Usa recursión."
         (when lista                               ; prueba-hazlo-de-nuevo
               (print (car lista))                 ; cuerpo
               (imprimir-elementos-recursivamente  ; llamada recursiva
                (cdr lista))))                     ; expresion-del-siguiente-paso

#        (print-elements-recursively animals)
       (imprimir-elementos-recursivamente animales)
#      < src..
     < src..


#      The pattern for @c{print-elements-recursively} is:
     El patrón para @c{imprimir-elementos-recursivamente} es:

#      - When the list is empty, do nothing.
     - Cuando la lista está vacía, no hacer nada.

#      - But when the list has at least one element,
     - Pero cuando la lista tiene al menos un elemento,

#        - act on the beginning of the list (the @c{car} of the list),
       - actúar al principio de la lista (el @c{car} de la lista),

#        - and make a recursive call on the rest (the @c{cdr}) of the list.
       - y hacer una llamada recursiva en el resto (el @c{cdr} de la lista).

# **** Recursive Pattern: @e{accumulate}
**** Patrón recursivo: @e{accumulate}

#      Another recursive pattern is called the @c{accumulate} pattern. In the
#      @c{accumulate} recursive pattern, an action is performed on every
#      element of a list and the result of that action is accumulated with the
#      results of performing the action on the other elements.
     Otro patrón recursivo se llama patrón @c{accumulate}. En el patrón
     recursivo @c{accumulate}, se realiza una acción en cada elemento de una
     lista y el resultado de esta acción se acumula con los resultados de
     realizar la acción en los otros elementos.

#      This is very like the ‘every’ pattern using @c{cons}, except that
#      @c{cons} is not used, but some other combiner.
     Esto es muy parecido al patron ‘every’ usando @c{cons}, excepto que
     no se utiliza @c{cons}, sino algun otro combinador.

#      The pattern is:
     El patrón es:

#      - If a list be empty, return zero or some other constant.
     - Si una lista está vacía, devuelve cero u otra constante.

#      - Else, act on the beginning of the list (the @c{car} of the list),
     - De lo contrario, actúa al principio de la lista (el @c{car} de la lista),

#        - and combine that acted-on element, using @c{+} or some other
#          combining function, with
       - y combina el elemento actual, utilizando @c{+} o alguna otra
         función de combinación, con

#        - a recursive call by the function on the rest (the @c{cdr}) of the
#          list.
       - una llamada recursiva a la función con el resto (el @c{cdr}) de la
         lista.


#      Here is an example:
     Aquí hay un ejemplo:

#      ..src > elisp
#        (defun add-elements (numbers-list)
#          "Add the elements of NUMBERS-LIST together."
#          (if (not numbers-list)
#              0
#            (+ (car numbers-list) (add-elements (cdr numbers-list)))))
#      < src..
     ..src > elisp
       (defun sumar-elementos (lista-de-numeros)
         "Suma los elementos de LISTA-DE-NUMEROS."
         (if (not lista-de-numeros)
             0
           (+ (car lista-de-numeros) (sumar-elementos (cdr lista-de-numeros)))))
     < src..

#      ..srci > elisp
#        > (add-elements '(1 2 3 4))
#        10
#      < srci..
     ..srci > elisp
       > (sumar-elementos '(1 2 3 4))
       10
     < srci..

#      See Section @l{#Making a List of Files}, for an example of the accumulate
#      pattern.
     Consulta la Seccion @l{#Creando una lista de ficheros}, para un ejemplo del
     patrón accumulate.

# **** Recursive Pattern: @e{keep}
**** Patrón recursivo: @e{keep}

#      A third recursive pattern is called the @c{keep} pattern. In the
#      @c{keep} recursive pattern, each element of a list is tested; the
#      element is acted on and the results are kept only if the element meets a
#      criterion.
     Un tercer patrón se llama el patrón @c{keep}. En el patrón recursivo
     @c{keep}, se prueba cada elemento de una lista; se actúa sobre el elemento
     y los resultados se conservan solo si el elemento cumple un criterio.

#      Again, this is very like the ‘every’ pattern, except the element is
#      skipped unless it meets a criterion.
     De nuevo, esto es muy parecido al patrón ‘every’, excepto que el elemento
     se descarta a menos que cumpla un criterio.

#      The pattern has three parts:
     El patrón tiene tres partes:

#      - If a list be empty, return @c{nil}.
     - Si una lista esta vacía, devuelve @c{nil}.

#      - Else, if the beginning of the list (the @c{car} of the list) passes a
#        test
     - De lo contrario, si el inicio de la lista (el @c{car}) pasa una prueba

#        - act on that element and combine it, using @c{cons} with
       - actuar sobre ese elemento y combinarlo, utilizando @c{cons} con

#        - a recursive call by the function on the rest (the @c{cdr}) of the
#          list.
       - una llamada recursiva a la función con el resto (el @c{cdr}) de la
         lista.

#      - Otherwise, if the beginning of the list (the @c{car} of the list)
#        fails the test
     - De lo contrario, si el inicio de la lista (el @c{car}) falla la prueba

#        - skip on that element,
       - saltar ese elemento,

#        - and, recursively call the function on the rest (the @c{cdr}) of the
#          list.
       - y, recursivamente llamar a la función sobre el resto (el @c{cdr}) de la
         lista.

#      Here is an example that uses @c{cond}:
     Aquí hay un ejemplo que usa @c{cond}:

#      ..src > elisp
     ..src > elisp
#        (defun keep-three-letter-words (word-list)
       (defun guardar-palabras-de-tres-letras (lista-palabras)
#          "Keep three letter words in WORD-LIST."
         "De la LISTA-PALABRAS, guarda las palabras de 3 letras."
#          (cond
         (cond
#           ;; First do-again-test: stop-condition
#           ((not word-list) nil)
          ;; Primera prueba-hazlo-de-nuevo: condicion-de-parada
          ((not lista-palabras) nil)

#           ;; Second do-again-test: when to act
#           ((eq 3 (length (symbol-name (car word-list))))
#            ;; combine acted-on element with recursive call on shorter list
#            (cons (car word-list) (keep-three-letter-words (cdr word-list))))
          ;; Segunda prueba-hazlo-de-nuevo: cuando actuar
          ((eq 3 (length (symbol-name (car lista-palabras))))
           ;; combina el elemento actual con la llamada recursiva en
           ;; una lista mas corta
           (cons (car lista-palabras) (guardar-palabras-de-tres-letras (cdr lista-palabras))))

#           ;; Third do-again-test: when to skip element;
#           ;;   recursively call shorter list with next-step expression
#           (t (keep-three-letter-words (cdr word-list)))))
          ;; Tercera prueba-hazlo-de-nuevo: cuando saltar el elemento;
          ;; llamada recursiva con una lista mas corta con la
          ;; expresion-del-siguiente-paso
          (t (guardar-palabras-de-tres-letras (cdr lista-palabras)))))
#      < src..
     < src..


#      ..srci > elisp
     ..srci > elisp
#        > (keep-three-letter-words '(one two three four five six))
#        (one two six)
       > (guardar-palabras-de-tres-letras '(uno dos tres cuatro cinco seis))
       (uno dos)
#      < srci..
     < srci..


#      It goes without saying that you need not use @c{nil} as the test for
#      when to stop; and you can, of course, combine these patterns.
     No hace falta decir que no es necesario utilizar @c{nil} como prueba
     para saber cuando parar; y, por su puesto, se pueden combinar estos patrones.

# *** Recursion without Deferments
*** Recursividad sin aplazamiento

#     Let's consider again what happens with the @c{triangle-recursively}
#     function. We will find that the intermediate calculations are deferred
#     until all can be done.
    Consideremos de nuevo lo que sucede con la función @c{triangulo-recursivo}.
    Encontraremos que los cálculos intermedios se postergan hasta que se pueda
    hacer todo.

#     Here is the function definition:
    Aquí está la definición de función:

#     ..src > elisp
#       (defun triangle-recursively (number)
#         "Return the sum of the numbers 1 through NUMBER inclusive.
#       Uses recursion."
#         (if (= number 1)                    ; do-again-test
#             1                               ; then-part
#           (+ number                         ; else-part
#              (triangle-recursively          ; recursive call
#               (1- number)))))               ; next-step-expression
#     < src..
    ..src > elisp
      (defun triangulo-recursivo (numero)
        "Devuelve la suma de números desde el 1 hasta e incluyendo a NUMERO.
      Usa recursion."
        (if (= numero 1)                    ; prueba-hazlo-de-nuevo
            1                               ; parte-then
          (+ numero                         ; parte-else
             (triangulo-recursivo           ; llamada recursiva
              (1- numero)))))               ; expresion-del-siguiente-paso
    < src..

#     What happens when we call this function with a argument of 7?
    ¿Qué ocurre cuando llamamos a esta función con un argumento de 7?

#     The first instance of the @c{triangle-recursively} function adds the
#     number 7 to the value returned by a second instance of
#     @c{triangle-recursively}, an instance that has been passed an argument
#     of 6. That is to say, the first calculation is:
    La primera instancia de la función @c{triangulo-recursivo} suma el
    número 7 al valor devuelto por una segunda instancia de
    @c{triangulo-recursivo}, una instancia a la que se ha pasado un argumento
    de 6. Es decir, el primer cálculo es:

#     ..src > elisp
#       (+ 7 (triangle-recursively 6))
#     < src..
    ..src > elisp
      (+ 7 (triangulo-recursivo 6))
    < src..

#     The first instance of @c{triangle-recursively}––you may want to think of
#     it as a little robot––cannot complete its job. It must hand off the
#     calculation for @c{(triangle-recursively 6)} to a second instance of the
#     program, to a second robot. This second individual is completely
#     different from the first one; it is, in the jargon, a ‘different
#     instantiation’. Or, put another way, it is a different robot. It is the
#     same model as the first; it calculates triangle numbers recursively; but
#     it has a different serial number.
    La primera instancia de @c{triangulo-recursivo}––tal vez quieres pensar en
    ella como un pequeño robot––no puede completar su trabajo. Debe pasar el
    cálculo a @c{(triangulo-recursivo 6)} una segunda instancia del programa, a
    un segundo robot. Este segundo individuo es completamente diferente del
    primero; en la jerga, una ‘instancia diferente’. O, dicho de otro modo, es
    un robot diferente. Es del mismo modelo que el primero; calcula números de
    triángulo recursivamente; pero tiene un número de serie diferente.

#     And what does @c{(triangle-recursively 6)} return?  It returns the number
#     6 added to the value returned by evaluating @c{triangle-recursively} with
#     an argument of 5. Using the robot metaphor, it asks yet another robot to
#     help it.
    ¿Y qué devuelve @c{(triangulo-recursivo 6)}? Devuelve el número 6 sumado al
    valor devuelto de evaluar @c{triangulo-recursivo} con un argumento
    de 5. Usando la metáfora del robot, le pide a otro robot que lo ayude.

#     Now the total is:
    Ahora el total es:

#     ..src > elisp
#       (+ 7 6 (triangle-recursively 5))
#     < src..
    ..src > elisp
      (+ 7 6 (triangulo-recursivo 5))
    < src..

#     And what happens next?
    ¿Y qué sucede después?

#     ..src > elisp
#       (+ 7 6 5 (triangle-recursively 4))
#     < src..
    ..src > elisp
      (+ 7 6 5 (triangulo-recursivo 4))
    < src..

#     Each time @c{triangle-recursively} is called, except for the last time,
#     it creates another instance of the program––another robot––and asks it to
#     make a calculation.
    Cada vez que se llama a @c{triangulo-recursivo}, excepto la última
    vez, se crea otra instancia del programa––otro robot––y le pide que
    haga un cálculo.

#     Eventually, the full addition is set up and performed:
    Eventualmente, se establece y realiza la suma completa:

#     ..src > elisp
#       (+ 7 6 5 4 3 2 1)
#     < src..
    ..src > elisp
      (+ 7 6 5 4 3 2 1)
    < src..

#     This design for the function defers the calculation of the first step
#     until the second can be done, and defers that until the third can be
#     done, and so on. Each deferment means the computer must remember what is
#     being waited on. This is not a problem when there are only a few steps,
#     as in this example. But it can be a problem when there are more steps.
    Este diseño de la función aplaza el cálculo del primer paso hasta que se
    pueda hacer el segundo, y aplaza este hasta que se puede hacer el tercero,
    y así sucesivamente. Cada aplazamiento significa que el ordenador debe recordar
    lo que se está esperado. Esto no es un problema cuando solo hay unos pocos
    pasos, como en este ejemplo. Pero puede ser un problema cuando hay más
    pasos.

# *** No Deferment Solution
*** Solucion sin aplazamiento

#     The solution to the problem of deferred operations is to write in a
#     manner that does not defer operations@n{12}. This requires writing to a
#     different pattern, often one that involves writing two function
#     definitions, an ‘initialization’ function and a ‘helper’ function.
    La solución al problema de deferir operaciones es escribir de una
    manera que no se pospongan las operaciones@n{12}. Esto requiere escribir en un
    patrón diferente, con frecuencia uno que implica escribir dos
    definiciones de función, una función de ‘inicialización’ y una función
    ‘auxiliar’.

#     The ‘initialization’ function sets up the job; the ‘helper’ function does
#     the work.
    La función de ‘inicializacion’ configura el trabajo; la función ‘auxiliar’
    hace el trabajo.

#     Here are the two function definitions for adding up numbers. They are so
#     simple, I find them hard to understand.
    Aquí estan las dos definiciones de funcion para sumar números. Son tan
    simples, que me cuesta entenderlas.

#     ..src > elisp
#       (defun triangle-initialization (number)
#         "Return the sum of the numbers 1 through NUMBER inclusive.
#       This is the ‘initialization’ component of a two function
#       duo that uses recursion."
#         (triangle-recursive-helper 0 0 number))
#     < src..
    ..src > elisp
      (defun triangulo-inicializacion (numero)
        "Devuelve la suma de números desde el 1 hasta e incluyendo a NUMERO.
      Este es el componente de ‘inicialización’ de una función doble
      que utiliza recursión"
        (triangulo-recursivo-auxiliar 0 0 numero))
    < src..

#     ..src > elisp
#       (defun triangle-recursive-helper (sum counter number)
#         "Return SUM, using COUNTER, through NUMBER inclusive.
#       This is the ‘helper’ component of a two function duo
#       that uses recursion."
#         (if (> counter number)
#             sum
#           (triangle-recursive-helper (+ sum counter)  ; sum
#                                      (1+ counter)     ; counter
#                                      number)))        ; number
#     < src..
    ..src > elisp
      (defun triangulo-recursivo-auxiliar (suma contador numero)
        "Devuelve la SUMA, usando CONTADOR, hasta e incluyendo NUMERO.
      Este es el componente ‘auxiliar’ de una funcion doble que
      utiliza recursión."
        (if (> contador numero)
            suma
          (triangulo-recursivo-auxiliar (+ suma contador)  ; suma
                                        (1+ contador)      ; contador
                                        numero)))          ; número
    < src..

#     Install both function definitions by evaluating them, then call
#     @c{triangle-initialization} with 2 rows:
    Instala ambas definiciones de función evaluandolas, luego llama a
    @c{triangulo-inicializacion} con 2 filas:

#     ..srci > elisp
#       > (triangle-initialization 2)
#       3
#     < srci..
    ..srci > elisp
      > (triangulo-inicializacion 2)
      3
    < srci..

#     The ‘initialization’ function calls the first instance of the ‘helper’
#     function with three arguments: zero, zero, and a number which is the
#     number of rows in the triangle.
    La función de ‘inicialización’ llama a la primera instancia de la función
    ‘auxiliar’ con tres argumentos: cero, cero, y un número que es el número
    de filas en el triángulo.

#     The first two arguments passed to the ‘helper’ function are
#     initialization values. These values are changed when
#     @c{triangle-recursive-helper} invokes new instances.@n{13}
    Los dos primeros argumentos que se pasan a la función ‘auxiliar’ son valores
    de inicialización. Estos valores cambian cuando
    @c{triangulo-recursivo-auxiliar} invoca nuevas instancias.@n{13}

#     Let's see what happens when we have a triangle that has one row.  (This
#     triangle will have one pebble in it!)
    Veamos que pasa cuando tenemos un triángulo que tiene una fila. (¡Este
    triángulo tendrá un guijarro en el!)

#     @c{triangle-initialization} will call its helper with the arguments @c{0
#     0 1}. That function will run the conditional test whether @c{(> counter
#     number)}:
    @c{triangulo-inicializacion} llamará a su auxiliar con los argumentos @c{0 0
    1}. Esta función ejecutará la prueba condicional @c{(> contador numero)}:

#     ..src > elisp
#       (> 0 1)
#     < src..
    ..src > elisp
      (> 0 1)
    < src..

#     and find that the result is false, so it will invoke the else-part of the
#     @c{if} clause:
    y encontrara que el resultado es falso, por lo que invocara la parte-else de
    la clausula @c{if}:

#     ..src > elisp
#           (triangle-recursive-helper
#            (+ sum counter)  ; sum plus counter ⇒ sum
#            (1+ counter)     ; increment counter ⇒ counter
#            number)          ; number stays the same
#     < src..
    ..src > elisp
          (triangulo-recursivo-auxiliar
           (+ suma contador)  ; suma más contador   ⇒ suma
           (1+ contador)      ; incrementa contador ⇒ contador
           numero)            ; numero se mentiene igual
    < src..

#     which will first compute:
    que al inicio calcula:

#     ..src > elisp
#       (triangle-recursive-helper (+ 0 0)  ; sum
#                                  (1+ 0)   ; counter
#                                  1)       ; number
#     < src..
    ..src > elisp
      (triangulo-recursivo-auxiliar (+ 0 0)  ; suma
                                    (1+ 0)   ; contador
                                    1)       ; numero
    < src..

#     which is:
    que es:

#     ..src > elisp
#       (triangle-recursive-helper 0 1 1)
#     < src..
    ..src > elisp
      (triangulo-recursivo-auxiliar 0 1 1)
    < src..

#     Again, @c{(> counter number)} will be false, so again, the Lisp
#     interpreter will evaluate @c{triangle-recursive-helper}, creating a new
#     instance with new arguments.
    Una vez mas, @c{(> contador numero)} será falso, por lo que de nuevo, el intérprete
    Lisp evaluará @c{triangulo-recursivo-auxiliar}, creando una nueva instancia
    con nuevos argumentos.

#     This new instance will be;
    Esta nueva instancia será;

#     ..src > elisp
#       (triangle-recursive-helper
#        (+ sum counter)  ; sum plus counter ⇒ sum
#        (1+ counter)     ; increment counter ⇒ counter
#        number)          ; number stays the same
#     < src..
    ..src > elisp
      (triangulo-recursivo-auxiliar
       (+ suma contador)  ; suma más contador ⇒ suma
       (1+ contador)      ; incrementa contador ⇒ contador
      numero)             ; numero se mentiene igual
    < src..

#     which is:
    que es:

#     ..src > elisp
#       (triangle-recursive-helper 1 2 1)
#     < src..
    ..src > elisp
      (triangulo-recursivo-auxiliar 1 2 1)
    < src..

#     In this case, the @c{(> counter number)} test will be true!  So the
#     instance will return the value of the sum, which will be 1, as expected.
    En este caso, la prueba @c{(> contador numero)} ¡será verdadera!  Así que la
    instancia devolverá el valor de la suma, que es 1, como se esperaba.

#     Now, let's pass @c{triangle-initialization} an argument of 2, to find out
#     how many pebbles there are in a triangle with two rows.
    Ahora, vamos a pasar a @c{triangulo-inicializacion} un argumento de 2, para
    encontrar cuántos guijarros hay en un triángulo con dos filas.

#     That function calls @c{(triangle-recursive-helper 0 0 2)}.
    Esta función haria la llamada @c{(triangulo-recursivo-auxiliar 0 0 2)}.

#     In stages, the instances called will be:
    En etapas, las instancias llamadas serán:

#     ..example >
    ..example >
#                                 sum counter number
#       (triangle-recursive-helper 0    1       2)
                                  suma contador número
      (triangulo-recursivo-auxiliar 0    1       2)

#       (triangle-recursive-helper 1    2       2)
      (triangulo-recursivo-auxiliar 1    2       2)

#       (triangle-recursive-helper 3    3       2)
      (triangulo-recursivo-auxiliar 3    3       2)
#     < example..
    < example..

#     When the last instance is called, the @c{(> counter number)} test will be
#     true, so the instance will return the value of @c{sum}, which will be 3.
    Cuando se llama a la última instancia, la prueba @c{(> contador numero)}
    será verdadera, por lo que la instancia devolverá el valor de @c{suma}, que
    será 3.

#     This kind of pattern helps when you are writing functions that can use
#     many resources in a computer.
    Este tipo de patrón ayuda cuando estás escribiendo funciones que pueden
    usar muchos recursos en un ordenador.

# ** Looping exercise
** Ejercicio de bucles

#    - Write a function similar to @c{triangle} in which each row has a value
#      which is the square of the row number. Use a @c{while} loop.
   - Escribe una función similar a @c{triangulo} en la que cada fila tenga un
     valor que sea el cuadrado del número de la fila. Usa un bucle @c{while}.

#    - Write a function similar to @c{triangle} that multiplies instead of adds
#      the values.
   - Escribe una función similar a @c{triangulo} que multiplique en lugar de
     sumar los valores.

#    - Rewrite these two functions recursively. Rewrite these functions using
#      @c{cond}.
   - Reescribe estas dos funciones recursivamente. Reescribe estas funciones
     usando @c{cond}.

#    - Write a function for Texinfo mode that creates an index entry at the
#      beginning of a paragraph for every @'{@@dfn} within the paragraph.  (In
#      a Texinfo file, @'{@@dfn} marks a definition. This book is written in
#      Texinfo.)
   - Escribe una función para el modo Texinfo que cree una entrada índice al
     principio de un párrafo para cada @'{@@dfn} dentro del parrafo. (En un
     fichero Texinfo, @'{@@dfn} marca una definición.)

#      Many of the functions you will need are described in two of the previous
#      chapters, Section @l{#Cutting and Storing Text}, and Section @l{#Yanking
#      Text Back}. If you use @c{forward-paragraph} to put the index entry at
#      the beginning of the paragraph, you will have to use @k{C-h f}
#      @%c{describe-function} to find out how to make the command go
#      backwards.
     Muchas de las funciones que necesitaras se describen en los dos capitulos anteriores,
     Secciones @l{#Cortar y Almacenar Texto} y @l{#Traer de regreso el texto}. Si usas
     @c{forward-paragraph} para poner la entrada de índice al principio del
     párrafo, tendrás que usar @k{C-h f} @%c{describe-function} para
     averiguar como hacer que el comando vaya hacia atrás.

#      For more information, see Section @l{https://www.gnu.org/software/texinfo/manual/texinfo/texinfo.html#Indicating<>Indicating
#      Definitions} in the @e{Texinfo Manual}, which goes to a Texinfo manual
#      in the current directory. Or, if you are on the Internet, see
#      @l{http://www.gnu.org/software/texinfo/manual/texinfo/}
   Para obtener más información, consulta la Seccion
   @l{https://www.gnu.org/software/texinfo/manual/texinfo/texinfo.html#Indicating<>Indicando Definiciones, Comandos, etc.}  en el
   @e{Manual de Texinfo} dentro de Emacs. O, tambien puedes consultarlo en
   internet en @l{http://www.gnu.org/software/texinfo/manual/texinfo/}

# * Regular Expression Searches
* Búsqueda de expresiones regulares

#   Regular expression searches are used extensively in GNU Emacs. The two
#   functions, @c{forward-sentence} and @c{forward-paragraph}, illustrate these
#   searches well. They use regular expressions to find where to move point.
#   The phrase ‘regular expression’ is often written as ‘regexp’.
  Las búsquedas de expresiones regulares se utilizan extensivamente en GNU
  Emacs. Las dos funciones @c{forward-sentence} y @c{forward-paragraph},
  ilustran bien estas búsquedas. Usan expresiones regulares para encontrar
  donde mover el punto. La frase ‘expresión regular’ se escribe a menudo
  como ‘regexp’.

#   Regular expression searches are described in Section @l{emacs.html#Regexp
#   Search<>Regular Expression Search} in @e(The GNU Emacs Manual), as well as
#   in Section @l{elisp.html#Regular Expressions<>Regular Expressions} in @e{The
#   GNU Emacs Lisp Reference Manual}. In writing this chapter, I am presuming
#   that you have at least a mild acquaintance with them. The major point to
#   remember is that regular expressions permit you to search for patterns as
#   well as for literal strings of characters. For example, the code in
#   @c{forward-sentence} searches for the pattern of possible characters that
#   could mark the end of a sentence, and moves point to that spot.
  Las búsquedas de expresiones regulares se describen en la Seccion
  @l{emacs.html#Regexp Search<>Búsqueda de Expresiónes Regulares} en @e{El
  Manual de GNU Emacs}, asi como en la Seccion @l{elisp.html#Regular
  Expressions<>Expresiones Regulares} en @e{El Manual de Referencia de GNU Emacs
  Lisp}. Al escribir este capítulo, estoy suponiendo que tienes al menos un leve
  conocimiento de esto. El punto principal a recordar es que las expresiones
  regulares te permiten buscar patrones, asi como cadenas literales de
  caracteres. Por ejemplo, el código en @c{forward-sentence} busca el patrón de
  posibles caracteres que podrían marcar el final de una oracion, y mueve el
  punto a ese lugar.

#   Before looking at the code for the @c{forward-sentence} function, it is
#   worth considering what the pattern that marks the end of a sentence must
#   be. The pattern is discussed in the next section; following that is a
#   description of the regular expression search function,
#   @c{re-search-forward}. The @c{forward-sentence} function is described in
#   the section following. Finally, the @c{forward-paragraph} function is
#   described in the last section of this chapter.  @c{forward-paragraph} is a
#   complex function that introduces several new features.
  Antes de mirar el código de la función @c{forward-sentence}, vale la pena
  considerar cual debe ser el patrón que marca el final de una oracion. El
  patrón se discute en la siguiente sección; a continuacion se describe
  la funcion de busqueda de expresiónes regulares, @c{re-search-forward}. La función
  @c{forward-sentence} se describe en la sección siguiente. Finalmente, la
  función @c{forward-paragraph} se describe en la última sección de este
  capítulo. @c{forward-paragraph} es una función compleja que introduce
  varias caracteristicas nuevas.

# ** The Regular Expression for @c{sentence-end}
** La expresión regular de @c{sentence-end}

#    The symbol @c{sentence-end} is bound to the pattern that marks the end of
#    a sentence. What should this regular expression be?
   El símbolo @c{sentence-end} esta ligado al patrón que marca el fin de una
   oracion. ¿Cuál deberia ser esta expresión regular?

#    Clearly, a sentence may be ended by a period, a question mark, or an
#    exclamation mark. Indeed, in English, only clauses that end with one of
#    those three characters should be considered the end of a sentence. This
#    means that the pattern should include the character set:
   Claramente, una oracion puede terminarse por un punto, un signo de
   interrogación, o un signo de exclamación. De hecho, en inglés, solo las
   oraciones que terminan con uno de estos tres caracteres deberían considerse
   como el final de una oracion. Esto significa que el patrón debe incluir el
   conjunto de caracteres:

#    ..example >
#      [.?!]
#    < example..
   ..example >
     [.?!]
   < example..

#    However, we do not want @c{forward-sentence} merely to jump to a period, a
#    question mark, or an exclamation mark, because such a character might be
#    used in the middle of a sentence. A period, for example, is used after
#    abbreviations. So other information is needed.
   Sin embargo, no queremos que @c{forward-sentence} salte simplemente a un
   punto, a un signo de interrogacion o a un signo de exclamación, porque tal
   carácter podría utilizarse en medio de una oracion. Un punto, por ejemplo,
   se usa después de las abreviaturas. Por lo tanto, se necesita mas información.

#    According to convention, you type two spaces after every sentence, but
#    only one space after a period, a question mark, or an exclamation mark in
#    the body of a sentence. So a period, a question mark, or an exclamation
#    mark followed by two spaces is a good indicator of an end of sentence.
#    However, in a file, the two spaces may instead be a tab or the end of a
#    line. This means that the regular expression should include these three
#    items as alternatives.
   Segun la convención, escribes dos espacios despues de cada oracion, pero solo
   un espacio después de un punto, un signo de interrogacion o un signo de
   exclamación en el cuerpo de una oracion. Asi que un punto, un signo de
   interrogacion o de exclamacion seguido por dos espacios es un buen indicador
   de un final de oracion. Sin embargo, en un archivo, los dos espacios pueden
   ser un tabulador o el fin de una línea. Esto significa que la expresión
   regular incluiría estos tres elementos como alternativas.

#    This group of alternatives will look like this:
   Este grupo de alternativas se vera asi:

#    ..example >
#      \\($\\| \\|  \\)
#             ^   ^^
#            TAB  SPC
#    < example..
   ..example >
     \\($\\| \\|  \\)
            ^   ^^
           TAB  SPC
   < example..

#    Here, @'c{$} indicates the end of the line, and I have pointed out where
#    the tab and two spaces are inserted in the expression. Both are inserted
#    by putting the actual characters into the expression.
   Aquí, @'c{$} indica el fin de la línea, ademas he señalado en la expresión
   donde se inserta el tabulador y los dos espacios. Ambos se insertan poniendo
   los caracteres reales en la expresión.

#    Two backslashes, @'c{\\}, are required before the parentheses and vertical
#    bars: the first backslash quotes the following backslash in Emacs; and the
#    second indicates that the following character, the parenthesis or the
#    vertical bar, is special.
   Antes de los parentesis y las barras verticales, se requiere dos
   barras invertidas @'c{\\}: la primera barra invertida cita la
   siguiente barra invertida en Emacs; y la segunda indica que el siguiente
   caracter, el paréntesis o la barra vertical, es especial.

#    Also, a sentence may be followed by one or more carriage returns, like
#    this:
   También, una oracion puede ir seguida por uno o más retornos de carro, como
   aqui:

#    ..example >
#      [
#      ]*
#    < example..
   ..example >
     [
     ]*
   < example..

#    Like tabs and spaces, a carriage return is inserted into a regular
#    expression by inserting it literally. The asterisk indicates that the
#    @k{RET} is repeated zero or more times.
   Al igual que los tabuladores y espacios, un retorno de carro se inserta en
   una expresión regular insertándolo literalmente. El asterisco indica
   que el @k{RET} se repite cero o más veces.

#    But a sentence end does not consist only of a period, a question mark or
#    an exclamation mark followed by appropriate space: a closing quotation
#    mark or a closing brace of some kind may precede the space. Indeed more
#    than one such mark or brace may precede the space. These require a
#    expression that looks like this:
   Pero una oracion no consiste solo en un punto, o un signo de interrogacion o
   de exclamación seguido de un espacio apropiado: una comilla de cierre o una
   llave de cierre de algún tipo puede preceder al espacio. De hecho, más de una
   marca o paréntesis pueden preceder al espacio. Estas requieren una expresión
   parecida a esta:

#    ..example >
#      []\"')}]*
#    < example..
   ..example >
     []\"')}]*
   < example..

#    In this expression, the first @'{]} is the first character in the
#    expression; the second character is @'c{"}, which is preceded by a @'c{\} to
#    tell Emacs the @'c{"} is @e{not} special. The last three characters are
#    @'c{'}, @'c{)}, and @'c(}).
   En esta expresión, el primer @'c{]} es el primer caracter en la expresión;
   el segundo caracter es @'c{"}, que está precedido por un @'c{\} para decirle
   a Emacs que el @'c{"} @e{no} es especial. Los últimos tres caracteres son @'c{'},
   @'c{)}, y @'c(}).

#    All this suggests what the regular expression pattern for matching the end
#    of a sentence should be; and, indeed, if we evaluate @c{sentence-end} we
#    find that it returns the following value:
   Todo esto sugiere cual deberia ser el patrón de la expresión regular para que
   coincida con el final de una oracion; y, de hecho, si evaluamos
   @c{sentence-end} encontraremos que devuelve el siguiente valor:

#    ..srci > elisp
#      > sentence-end
#      "[.?!][]\"')}]*\\($\\|     \\|  \\)[
#      ]*"
#    < srci..
   ..srci > elisp
     > sentence-end
     "[.?!][]\"')}]*\\($\\|     \\|  \\)[
     ]*"
   < srci..

#    (Well, not in GNU Emacs 22; that is because of an effort to make the
#    process simpler and to handle more glyphs and languages. When the value
#    of @c{sentence-end} is @c{nil}, then use the value defined by the function
#    @c{sentence-end}.  (Here is a use of the difference between a value and a
#    function in Emacs Lisp.)  The function returns a value constructed from
#    the variables @c{sentence-end-base}, @c{sentence-end-double-space},
#    @c{sentence-end-without-period}, and @c{sentence-end-without-space}. The
#    critical variable is @c{sentence-end-base}; its global value is similar to
#    the one described above but it also contains two additional quotation
#    marks. These have differing degrees of curliness. The
#    @c{sentence-end-without-period} variable, when true, tells Emacs that a
#    sentence may end without a period, such as text in Thai.)
   (Bueno, no en GNU Emacs 22; eso se debe a un esfuerzo por hacer el proceso
   simple y manejar más símbolos y lenguajes. Cuando el valor de
   @c{sentence-end} es @c{nil}, entonces utiliza el valor definido por la
   función @c{sentence-end}. (Aquí se utiliza la diferencia entre un valor y una
   función en Emacs Lisp.) La función devuelve un valor construido a partir de
   las variables @c{sentence-end-base}, @c{sentence-end-double-space},
   @c{sentence-end-without-period}, y @c{sentence-end-without-space}. La
   variable crítica es @c{sentence-end-base}; su valor global es similar al
   descrito anteriormente, pero también contiene dos marcas de cita
   adicionales. Estas tienen diferentes grados de curvatura. La variable
   @c{sentence-end-without-period}, cuando es verdadera, le dice a Emacs que una
   oracion puede finalizar sin un punto, como en texto en Tailandés.)

# ** The @c{re-search-forward} Function
** La Función @c{re-search-forward}

#    The @c{re-search-forward} function is very like the @c{search-forward}
#    function.  (See Section @l{#The @c{search-forward} Function}.)
   La función @c{re-search-forward} es similar a la función
   @c{search-forward}. (Consulta la Seccion @l{#La Función @c{search-forward}}.)

#    @c{re-search-forward} searches for a regular expression. If the search is
#    successful, it leaves point immediately after the last character in the
#    target. If the search is backwards, it leaves point just before the first
#    character in the target. You may tell @c{re-search-forward} to return
#    @c{t} for true.  (Moving point is therefore a ‘side effect’.)
   @c{re-search-forward} busca una expresión regular. Si la búsqueda es exitosa,
   deja el punto inmediatamente después del último caracter en el objetivo. Si
   la búsqueda es hacia atrás, deja el punto antes del primer caracter en el
   objetivo. Puedes decirle a @c{re-search-forward} que regrese @c{t} por
   verdadero. (El movimiento del punto es por la tanto un ‘efecto secundario’.)

#    Like @c{search-forward}, the @c{re-search-forward} function takes four
#    arguments:
   Al igual que @c{search-forward}, la función @c{re-search-forward} toma cuatro
   argumentos:

#    1. The first argument is the regular expression that the function searches
#       for. The regular expression will be a string between quotation marks.
   1. El primer argumento es la expresión regular que busca la función. La
      expresión regular será una cadena entre comillas.

#    2. The optional second argument limits how far the function will search;
#       it is a bound, which is specified as a position in the buffer.
   2. El segundo argumento opcional limita el grado de busqueda de la función;
      es un valor ligado con una posición especifica en el búfer.

#    3. The optional third argument specifies how the function responds to
#       failure: @c{nil} as the third argument causes the function to signal an
#       error (and print a message) when the search fails; any other value
#       causes it to return @c{nil} if the search fails and @c{t} if the search
#       succeeds.
   3. El tercer argumento opcional especifica cómo la función responde al
      fallo: @c{nil} como tercer argumento hace que la función señale
      un error (e imprima un mensaje) cuando la búsqueda falla; cualquier
      otro valor hace que devuelva @c{nil} si la búsqueda falla y @c{t} si la
      búsqueda tiene éxito.

#    4. The optional fourth argument is the repeat count. A negative repeat
#       count causes @c{re-search-forward} to search backwards.
   4. El cuarto argumento opcional es el contador de repeticiones. Un contador
      de repeticion negativo hace que @c{re-search-forward} busque hacia atrás.


#    The template for @c{re-search-forward} looks like this:
   La plantilla para @c{re-search-forward} se ve asi:

#    ..src > elisp
#      (re-search-forward "regular-expression"
#                      limit-of-search
#                      what-to-do-if-search-fails
#                      repeat-count)
#    < src..
   ..src > elisp
     (re-search-forward "expresion-regular"
                        limite-de-busqueda
                        que-hacer-si-falla-la-busqueda
                        contador-de-repeticiones)
   < src..

#    The second, third, and fourth arguments are optional. However, if you
#    want to pass a value to either or both of the last two arguments, you must
#    also pass a value to all the preceding arguments. Otherwise, the Lisp
#    interpreter will mistake which argument you are passing the value to.
   El segundo, tercer, y cuarto argumentos son opcionales. Sin embargo, si se
   quiere pasar un valor a uno o ambos de los últimos dos argumentos, se debe
   también pasar un valor a todos los argumentos anteriores. De otro modo,
   el intérprete Lisp confundira el argumento al que estás pasando el valor.

#    In the @c{forward-sentence} function, the regular expression will be the
#    value of the variable @c{sentence-end}. In simple form, that is:
   En la función @c{forward-sentence}, la expresión regular será el valor de
   la variable @c{sentence-end}. En forma simple, esto es:

#    ..example >
#      "[.?!][]\"')}]*\\($\\|  \\|  \\)[
#      ]*"
#    < example..
   ..example >
     "[.?!][]\"')}]*\\($\\|  \\|  \\)[
     ]*"
   < example..

#    The limit of the search will be the end of the paragraph (since a sentence
#    cannot go beyond a paragraph). If the search fails, the function will
#    return @c{nil}; and the repeat count will be provided by the argument to
#    the @c{forward-sentence} function.
   El límite de la búsqueda será el fin del párrafo (ya que una oracion no puede
   ir mas alla de un párrafo). Si la búsqueda falla, la función devuelve @c{nil}, y
   el argumento del contador de repeticion será pasado a la función
   @c{forward-sentence}.

# ** The @c{forward-sentence} Function
** La Función @c{forward-sentence}

#    The command to move the cursor forward a sentence is a straightforward
#    illustration of how to use regular expression searches in Emacs Lisp.
#    Indeed, the function looks longer and more complicated than it is; this is
#    because the function is designed to go backwards as well as forwards; and,
#    optionally, over more than one sentence. The function is usually bound to
#    the key command @k{M-e}.
   El comando para mover el cursor hacia adelante una oracion es una
   ilustración directa de cómo usar búsqueda de expresiones regulares en Emacs
   Lisp. De hecho, la función parece más larga y más complicada de lo que es;
   esto se debe a que la función está diseñada para ir hacia atrás y hacia
   adelante; y, opcionalmente, mas de una oracion. La función normalmente
   está vinculada al comando @k{M-e}.

#    Here is the code for @c{forward-sentence}:
   Aquí está la código de @c{forward-sentence}:

#    ..src > elisp
   ..src > elisp
#      (defun forward-sentence (&optional arg)
     (defun forward-sentence (&optional arg)
#        "Move forward to next ‘sentence-end’. With argument, repeat.
#      With negative argument, move backward repeatedly to ‘sentence-beginning’.
       "Avansa al siguiente ‘sentence-end’. Con un argumento, se repite.
     Con un argumento negativo, avanza hacia atras repetidamente al ‘sentence-beginning’.

#      The variable ‘sentence-end’ is a regular expression that matches ends of
#      sentences. Also, every paragraph boundary terminates sentences as well."
     La variable ‘sentence-end’ es una expresión regular que corresponde al
     fin de la oracion. Ademas, cada limite de párrafo tambien termina una oracion."
#        (interactive "p")
       (interactive "p")
#        (or arg (setq arg 1))
#        (let ((opoint (point))
#              (sentence-end (sentence-end)))
#          (while (< arg 0)
#            (let ((pos (point))
#                  (par-beg (save-excursion (start-of-paragraph-text) (point))))
#             (if (and (re-search-backward sentence-end par-beg t)
#                      (or (< (match-end 0) pos)
#                          (re-search-backward sentence-end par-beg t)))
#                 (goto-char (match-end 0))
#               (goto-char par-beg)))
#            (setq arg (1+ arg)))
#          (while (> arg 0)
#            (let ((par-end (save-excursion (end-of-paragraph-text) (point))))
#             (if (re-search-forward sentence-end par-end t)
#                 (skip-chars-backward " \t\n")
#               (goto-char par-end)))
#            (setq arg (1- arg)))
#          (constrain-to-field nil opoint t)))
       (or arg (setq arg 1))
       (let ((opoint (point))
             (sentence-end (sentence-end)))
         (while (< arg 0)
           (let ((pos (point))
                 (par-beg (save-excursion (start-of-paragraph-text) (point))))
            (if (and (re-search-backward sentence-end par-beg t)
                     (or (< (match-end 0) pos)
                         (re-search-backward sentence-end par-beg t)))
                (goto-char (match-end 0))
              (goto-char par-beg)))
           (setq arg (1+ arg)))
         (while (> arg 0)
           (let ((par-end (save-excursion (end-of-paragraph-text) (point))))
            (if (re-search-forward sentence-end par-end t)
                (skip-chars-backward " \t\n")
              (goto-char par-end)))
           (setq arg (1- arg)))
         (constrain-to-field nil opoint t)))
#    < src..
   < src..

#    The function looks long at first sight and it is best to look at its
#    skeleton first, and then its muscle. The way to see the skeleton is to
#    look at the expressions that start in the left-most columns:
   La función se ve larga a primera vista y lo mejor es mirar primero su
   esqueleto, y luego su músculo. La forma de ver el esqueleto es mirar
   las expresiones que comienzan en las columnas de la izquierda:

#    ..src > elisp
#      (defun forward-sentence (&optional arg)
#        "documentation…"
#        (interactive "p")
#        (or arg (setq arg 1))
#        (let ((opoint (point)) (sentence-end (sentence-end)))
#          (while (< arg 0)
#            (let ((pos (point))
#                  (par-beg (save-excursion (start-of-paragraph-text) (point))))
#             rest-of-body-of-while-loop-when-going-backwards
#          (while (> arg 0)
#            (let ((par-end (save-excursion (end-of-paragraph-text) (point))))
#             rest-of-body-of-while-loop-when-going-forwards
#          handle-forms-and-equivalent
#    < src..
   ..src > elisp
     (defun forward-sentence (&optional arg)
       "documentacion…"
       (interactive "p")
       (or arg (setq arg 1))
       (let ((opoint (point)) (sentence-end (sentence-end)))
         (while (< arg 0)
           (let ((pos (point))
                 (par-beg (save-excursion (start-of-paragraph-text) (point))))
            resto-del-cuerpo-del-bucle-while-cuando-va-hacia-atras
         (while (> arg 0)
           (let ((par-end (save-excursion (end-of-paragraph-text) (point))))
            resto-del-cuerpo-del-bucle-while-cuando-va-hacia-adelante
         manejar-formularios-y-equivalentes
   < src..

#    This looks much simpler!  The function definition consists of
#    documentation, an @c{interactive} expression, an @c{or} expression, a
#    @c{let} expression, and @c{while} loops.
   ¡Esto parece mucho mas simple! La definición de la función consiste en la
   documentación, una expresión @c{interactive}, una expresión @c{or}, una
   expresión @c{let}, y bucles @c{while}.

#    Let's look at each of these parts in turn.
   Veamos cada una de estas partes por separado.

#    We note that the documentation is thorough and understandable.
   Observamos que la documentación es completa y comprensible.

#    The function has an @c{interactive "p"} declaration. This means that the
#    processed prefix argument, if any, is passed to the function as its
#    argument.  (This will be a number.)  If the function is not passed an
#    argument (it is optional) then the argument @c{arg} will be bound to 1.
   La función tiene una declaración @c{interactive "p"}. Esto signifca que el
   argumento prefijo procesado, si lo hay, pasa a la función como su
   argumento. (Este será un número.) Si no se pasa un argumento a la función (es
   opcional) entonces el argumento @c{arg} será vinculara a 1.

#    When @c{forward-sentence} is called non-interactively without an argument,
#    @c{arg} is bound to @c{nil}. The @c{or} expression handles this. What it
#    does is either leave the value of @c{arg} as it is, but only if @c{arg} is
#    bound to a value; or it sets the value of @c{arg} to 1, in the case when
#    @c{arg} is bound to @c{nil}.
   Cuando @c{forward-sentence} se llama no interactivamente sin un argumento,
   @c{arg} está vinculado a @c{nil}. La expresión @c{or} maneja esto. Lo que
   hace es dejar el valor de @c{arg} como esta, pero solo si @c{arg} está ligado
   a un valor; de otro modo asigna el valor de @c{arg} a 1, en el caso de que
   @c{arg} este ligado a @c{nil}.

#    Next is a @c{let}. That specifies the values of two local variables,
#    @c{point} and @c{sentence-end}. The local value of point, from before the
#    search, is used in the @c{constrain-to-field} function which handles forms
#    and equivalents. The @c{sentence-end} variable is set by the
#    @c{sentence-end} function.
   Lo siguiente es un @c{let}. Especifica los valores de dos variables
   locales @c{point} y @c{sentence-end}. El valor local del punto, desde antes
   de la búsqueda, se utiliza en la función @c{constrain-to-field} que maneja
   formularios y equivalentes. La variable @c{sentence-end} se establece por
   la función @c{sentence-end}.

# *** The @c{while} loops
*** Los bucles @c{while}

#     Two @c{while} loops follow. The first @c{while} has a true-or-false-test
#     that tests true if the prefix argument for @c{forward-sentence} is a
#     negative number. This is for going backwards. The body of this loop is
#     similar to the body of the second @c{while} clause, but it is not exactly
#     the same. We will skip this @c{while} loop and concentrate on the second
#     @c{while} loop.
    Siguen dos bucles @c{while}. El primer @c{while} tiene una
    prueba-verdadero-o-falso que es verdadero si el argumento prefijo de
    @c{forward-sentence} es un número negativo. Esto es para ir hacia atras. El
    cuerpo de este bucle es similar al cuerpo del segundo @c{while},
    pero no es exactamente el mismo. Pasaremos de este bucle @c{while} y
    nos centraremos en el segundo @c{while}.

#     The second @c{while} loop is for moving point forward. Its skeleton
#     looks like this:
    El segundo bucle @c{while} es para mover el punto hacia adelante. Su
    esqueleto luce asi:

#     ..src > elisp
#       (while (> arg 0)            ; true-or-false-test
#         (let varlist
#           (if (true-or-false-test)
#               then-part
#             else-part
#         (setq arg (1- arg))))     ; while loop decrementer
#     < src..
    ..src > elisp
      (while (> arg 0)            ; prueba-verdadero-o-falso
        (let varlist
          (if (prueba-verdadero-o-falso)
              parte-then
            parte-else
        (setq arg (1- arg))))     ; decremento del bucle while
    < src..

#     The @c{while} loop is of the decrementing kind.  (See Section @l{#Loop
#     with a Decrementing Counter}.)  It has a true-or-false-test that tests
#     true so long as the counter (in this case, the variable @c{arg}) is
#     greater than zero; and it has a decrementer that subtracts 1 from the
#     value of the counter every time the loop repeats.
    El bucle @c{while} es de tipo decreciente. (Consulta la Seccion @l{#Bucle con
    un contador decreciente}.) Tiene una prueba-verdadero-o-falso que regresa
    verdadero siempre y cuando el contador (en este caso, la variable @c{arg})
    sea mayor que cero; y tiene un decremento que resta 1 del valor del contador
    cada vez que el bucle se repite.

#     If no prefix argument is given to @c{forward-sentence}, which is the most
#     common way the command is used, this @c{while} loop will run once, since
#     the value of @c{arg} will be 1.
    Si no se da un argumento prefijo a @c{forward-sentece}, que es lo mas
    habitual, este bucle @c{while} se ejecutará una vez, ya que el valor de
    @c{arg} será 1.

#     The body of the @c{while} loop consists of a @c{let} expression, which
#     creates and binds a local variable, and has, as its body, an @c{if}
#     expression.
    El cuerpo del bucle @c{while} consite en una expresión @c{let}, que crea
    y vincula una variable local, y tiene, como su cuerpo, una expresión @c{if}.

#     The body of the @c{while} loop looks like this:
    El cuerpo del bucle @c{while} se ve asi:

#     ..src > elisp
#       (let ((par-end
#              (save-excursion (end-of-paragraph-text) (point))))
#         (if (re-search-forward sentence-end par-end t)
#             (skip-chars-backward " \t\n")
#           (goto-char par-end)))
#     < src..
    ..src > elisp
      (let ((par-end
             (save-excursion (end-of-paragraph-text) (point))))
        (if (re-search-forward sentence-end par-end t)
            (skip-chars-backward " \t\n")
          (goto-char par-end)))
    < src..

#     The @c{let} expression creates and binds the local variable @c{par-end}.
#     As we shall see, this local variable is designed to provide a bound or
#     limit to the regular expression search. If the search fails to find a
#     proper sentence ending in the paragraph, it will stop on reaching the end
#     of the paragraph.
    La expresión @c{let} crea y enlaza la variable local @c{par-end}. Como
    veremos, esta variable local está diseñada para proporcionar un limite a la
    búsqueda de expresiónes regulares. Si la búsqueda no encuentra una
    oracion apropiada que termine en el párrafo, se detendra al llegar al final
    del párrafo.

#     But first, let us examine how @c{par-end} is bound to the value of the
#     end of the paragraph. What happens is that the @c{let} sets the value of
#     @c{par-end} to the value returned when the Lisp interpreter evaluates the
#     expression
    Pero primero, examinaremos cómo @c{par-end} se liga al valor del
    fin del párrafo. Lo que ocurre es que el @c{let} asigna el
    valor de @c{par-end} al valor devuelto cuando el intérprete evalúa la
    expresión.

#     ..src > elisp
#       (save-excursion (end-of-paragraph-text) (point))
#     < src..
    ..src > elisp
      (save-excursion (end-of-paragraph-text) (point))
    < src..

#     In this expression, @c{(end-of-paragraph-text)} moves point to the end of
#     the paragraph, @c{(point)} returns the value of point, and then
#     @c{save-excursion} restores point to its original position. Thus, the
#     @c{let} binds @c{par-end} to the value returned by the @c{save-excursion}
#     expression, which is the position of the end of the paragraph.  (The
#     @c{end-of-paragraph-text} function uses @c{forward-paragraph}, which we
#     will discuss shortly.)
    En esta expresión, @c{(end-of-paragraph-text)} mueve el punto al fin del
    párrafo, @c{(point)} devuelve el valor del punto, y luego
    @c{save-excursion} restaura el punto a su posición original. De este
    modo, el @c{let} liga @c{par-end} al valor devuelto por la expresión
    @c{save-excursion}, que es la posición del fin del párrafo.  (La función
    @c{end-of-paragraph-text} utiliza @c{forward-paragraph}, que discutiremos en
    breve.)

#     Emacs next evaluates the body of the @c{let}, which is an @c{if}
#     expression that looks like this:
    A continuacion Emacs evalúa el cuerpo del @c{let}, que es una expresión
    @c{if}:

#     ..src > elisp
#       (if (re-search-forward sentence-end par-end t) ; if-part
#           (skip-chars-backward " \t\n")              ; then-part
#         (goto-char par-end)))                        ; else-part
#     < src..
    ..src > elisp
      (if (re-search-forward sentence-end par-end t) ; parte-if
          (skip-chars-backward " \t\n")              ; parte-then
        (goto-char par-end)))                        ; parte-else
    < src..

#     The @c{if} tests whether its first argument is true and if so, evaluates
#     its then-part; otherwise, the Emacs Lisp interpreter evaluates the
#     else-part. The true-or-false-test of the @c{if} expression is the
#     regular expression search.
    El @c{if} comprueba si su primer argumento es verdadero y es así, evalúa su
    parte-then; de lo contrario, el intérprete Emacs Lisp evalúa la parte-else.
    La prueba-verdadero-o-falso de la expresión @c{if} es la búsqueda de la
    expresión regular.

#     It may seem odd to have what looks like the ‘real work’ of the
#     @c{forward-sentence} function buried here, but this is a common way this
#     kind of operation is carried out in Lisp.
    Puede parecer extraño tener lo que parece ser el ‘trabajo real’ de la función
    @c{forward-sentence} enterrado aqui, pero esta es una forma común de
    realizar este tipo de operación en Lisp.

# *** The regular expression search
*** La búsqueda de expresiones regulares

#     The @c{re-search-forward} function searches for the end of the sentence,
#     that is, for the pattern defined by the @c{sentence-end} regular
#     expression. If the pattern is found––if the end of the sentence is
#     found––then the @c{re-search-forward} function does two things:
    La función @c{re-search-forward} busca el fin de la oracion, es decir, el
    patrón definido por la expresión regular @c{sentence-end}. Si se encuentra
    el patrón––si se encuentra el fin de la oracion––entonces la función
    @c{re-search-forward} hace dos cosas:

#     1. The @c{re-search-forward} function carries out a side effect, which is
#        to move point to the end of the occurrence found.
    1. La función @c{re-search-forward} realiza un efecto secundario, que es mover
       el punto al final de la ocurrencia encontrada.

#     2. The @c{re-search-forward} function returns a value of true. This is
#        the value received by the @c{if}, and means that the search was
#        successful.
    2. La función @c{re-search-forward} devuelve un valor verdadero. Este es
       el valor recibido por el @c{if}, y significa que la búsqueda fué
       exitosa.


#     The side effect, the movement of point, is completed before the @c{if}
#     function is handed the value returned by the successful conclusion of the
#     search.
    El efecto secundario, el movimiento del punto se completa antes de que la
    función @c{if} reciva el valor devuelto por la conclusión exitosa de la
    búsqueda.

#     When the @c{if} function receives the value of true from a successful
#     call to @c{re-search-forward}, the @c{if} evaluates the then-part, which
#     is the expression @c{(skip-chars-backward " \t\n")}. This expression
#     moves backwards over any blank spaces, tabs or carriage returns until a
#     printed character is found and then leaves point after the character.
#     Since point has already been moved to the end of the pattern that marks
#     the end of the sentence, this action leaves point right after the closing
#     printed character of the sentence, which is usually a period.
    Cuando la función @c{if} recibe el valor verdadero desde una llamada exitosa
    a @c{re-search-forward}, el @c{if} evalúa la parte-then que es la expresión
    @c{(skip-chars-backward "\t\n")}. Esta expresión se mueve hacia atrás a
    través de cualquier espacio en blanco, tabulador o retorno de carro hasta
    encontrar un caracter imprimible y deja el punto después del caracter.
    Como el punto ya se ha movido al final del patron que marca el final de la
    oracion, esta accion deja el punto justo despues del caracter imprimible de
    cierre de la oracion, que suele ser un punto.

#     On the other hand, if the @c{re-search-forward} function fails to find a
#     pattern marking the end of the sentence, the function returns false. The
#     false then causes the @c{if} to evaluate its third argument, which is
#     @c{(goto-char par-end)}: it moves point to the end of the paragraph.
    Por otro lado, si la función @c{re-search-forward} no encuentra
    un patrón que marque el fin de la oracion, la función devuelve falso. El
    falso hace que @c{if} evalue su tercer argumento, que es
    @c{(goto-char par-end)}: esto mueve el punto al final del párrafo.

#     (And if the text is in a form or equivalent, and point may not move
#     fully, then the @c{constrain-to-field} function comes into play.)
    (Y si el texto está en una forma o equivalente, y el punto no se
    mueve completamente, entonces entra en juego la función
    @c{constrain-to-field}.)

#     Regular expression searches are exceptionally useful and the pattern
#     illustrated by @c{re-search-forward}, in which the search is the test of
#     an @c{if} expression, is handy. You will see or write code incorporating
#     this pattern often.
    La búsqueda de expresiones regulares son excepcionalmente útiles y el
    patrón ilustrado por @c{re-search-forward}, en el que la búsqueda es la
    prueba de una expresión @c{if}, es facil de manejar. Veras o escribirás código
    incorporando este patrón con frecuencia.

# ** @c{forward-paragraph}: a Goldmine of Functions
** @c{forward-paragraph}: una mina de oro de funciones

#    The @c{forward-paragraph} function moves point forward to the end of the
#    paragraph. It is usually bound to @k(M-}) and makes use of a number of
#    functions that are important in themselves, including @c{let*},
#    @c{match-beginning}, and @c{looking-at}.
   La función @c{forward-paragraph} mueve el punto al fin del párrafo. Por
   lo general esta asociado a @k(M-}) y hace uso de un número de funciones
   que son importantes en sí mismas, incluyendo @c{let*}, @c{match-beginning}, y
   @c{looking-at}.

#    The function definition for @c{forward-paragraph} is considerably longer
#    than the function definition for @c{forward-sentence} because it works
#    with a paragraph, each line of which may begin with a fill prefix.
  La definición de función de @c{forward-paragraph} es considerablemente
   mas extensa que la definición de función de @c{forward-sentence} porque
   trabaja con un párrafo, cada línea de la cual puede empezar con un prefijo de
   relleno.

#    A fill prefix consists of a string of characters that are repeated at the
#    beginning of each line. For example, in Lisp code, it is a convention to
#    start each line of a paragraph-long comment with @'{;;; }. In Text mode,
#    four blank spaces make up another common fill prefix, creating an indented
#    paragraph.  (See Section @l{emacs.html#Fill Prefix<>Fill Prefix} in @e(The
#    GNU Emacs Manual), for more information about fill prefixes.)
   Un prefijo de relleno consiste en una cadena de caracteres que se repite al
   principio de cada línea. Por ejemplo, en el código Lisp, es una convención
   empezar cada línea de un comentario de un párrafo extenso con @'{;;; }. En el
   modo Texto, cuatro espacios en blanco forman otro prefijo común de relleno,
   creando un párrafo indentado. (Consulta la Sección @l{emacs.html#Fill
   Prefix<>Prefijo de relleno} en @e(El Manual de GNU Emacs) para más
   información acerca de los prefijos de relleno.)

#    The existence of a fill prefix means that in addition to being able to
#    find the end of a paragraph whose lines begin on the left-most column, the
#    @c{forward-paragraph} function must be able to find the end of a paragraph
#    when all or many of the lines in the buffer begin with the fill prefix.
   La existencia de un prefijo de relleno significa que, además de poder
   encontrar el fin de un párrafo cuyas líneas empiezan en la columna más a la
   izquierda, la función @c{forward-paragraph} debe ser capaz de encontrar el
   final de un párrafo cuando todas o muchas de las líneas en el búfer
   empiezan con el prefijo de relleno.

#    Moreover, it is sometimes practical to ignore a fill prefix that exists,
#    especially when blank lines separate paragraphs. This is an added
#    complication.
   Ademas, a veces es práctico ignorar un prefijo de relleno que existe,
   especialmente cuando las líneas en blanco separan los párrafos. Esto es una
   complicación añadida.

#    Rather than print all of the @c{forward-paragraph} function, we will only
#    print parts of it. Read without preparation, the function can be
#    daunting!
   En vez de imprimir toda la función @c{forward-paragraph}, solo
   imprimiremos partes de la misma. ¡Leer la función sin preparación, puede
   ser desalentador!

#    In outline, the function looks like this:
   En general, la función tiene este aspecto:

#    ..src > elisp
#      (defun forward-paragraph (&optional arg)
#        "documentation…"
#        (interactive "p")
#        (or arg (setq arg 1))
#        (let*
#            varlist
#          (while (and (< arg 0) (not (bobp)))     ; backward-moving-code
#            …
#          (while (and (> arg 0) (not (eobp)))     ; forward-moving-code
#            …
#    < src..
   ..src > elisp
     (defun forward-paragraph (&optional arg)
       "documentacion…"
       (interactive "p")
       (or arg (setq arg 1))
       (let*
           varlist
         (while (and (< arg 0) (not (bobp)))     ; codigo-de-movimiento-hacia-atras
           …
         (while (and (> arg 0) (not (eobp)))     ; codigo-de-movimiento-hacia-adelante
           …
   < src..

#    The first parts of the function are routine: the function's argument list
#    consists of one optional argument. Documentation follows.
   Las primeras partes de la función son rutinarias: la  lista de argumentos
   de la función consiste en un argumento opcional. Luego se presenta
   la documentación.

#    The lower case @'c{p} in the @c{interactive} declaration means that the
#    processed prefix argument, if any, is passed to the function. This will
#    be a number, and is the repeat count of how many paragraphs point will
#    move. The @c{or} expression in the next line handles the common case when
#    no argument is passed to the function, which occurs if the function is
#    called from other code rather than interactively. This case was described
#    earlier.  (See Section @l{#The @c{forward-sentence} Function}.)
#    Now we reach the end of the familiar part of this function.
   La letra minúscula @'c{p} en la declaración @c{interactive} significa que el
   argumento prefijo se procesa, si lo hay, pasa a la función. Este será un
   número, y es el contador de repeticion de cuántos párrafos se moverá el
   punto. La expresión @c{or} en la siguiente línea maneja el caso común cuando
   no se pasa ningun argumento a la función, esto ocurre si la función se
   llama desde otro código en lugar de interactivamente. Este caso se describio
   anteriormente. (Consulta la Seccion @l{#La Función @c{forward-sentence}}.) Ahora
   llegamos al final de la parte familiar de esta función.

# *** The @c{let*} expression
*** La expresión @c{let*}

#     The next line of the @c{forward-paragraph} function begins a @c{let*}
#     expression. This is a different than @c{let}. The symbol is @c{let*}
#     not @c{let}.
    La siguiente línea en la función @c{forward-paragraph} empieza con una
    expresión @c{let*}. Esto es diferente a @c{let}. El símbolo es
    @c{let*} no @c{let}.

#     The @c{let*} special form is like @c{let} except that Emacs sets each
#     variable in sequence, one after another, and variables in the latter part
#     of the varlist can make use of the values to which Emacs set variables in
#     the earlier part of the varlist.
    La forma especial @c{let*} es como @c{let} excepto que Emacs establece cada
    variable en secuencia, una después de otra, y las variables en la última
    parte de la varlist pueden hacen uso de los valores a los que Emacs asignó
    las variables al principio la varlist.

#     (Section @l{#@c{save-excursion} en @c{append-to-buffer}}.)
    (Seccion @l{#@c{save-excursion} en @c{append-to-buffer}}.)

#     In the @c{let*} expression in this function, Emacs binds a total of seven
#     variables: @c{opoint}, @c{fill-prefix-regexp}, @c{parstart}, @c{parsep},
#     @c{sp-parstart}, @c{start}, and @c{found-start}.
    En la expresión @c{let*} en esta función, Emacs asigna un total de siete
    variables: @c{opoint}, @c{fill-prefix-regexp}, @c{parstart}, @c{parsep},
    @c{sp-parstart}, @c{start}, y @c{found-start}.

#     The variable @c{parsep} appears twice, first, to remove instances of
#     @'c{^}, and second, to handle fill prefixes.
    La variable @c{parsep} aparece dos veces, primero, para eliminar instancias
    de @'c{^}, y segundo, para manejar prefijos de relleno.

#     The variable @c{opoint} is just the value of @c{point}. As you can
#     guess, it is used in a @c{constrain-to-field} expression, just as in
#     @c{forward-sentence}.
    La variable @c{opoint} es solo el valor de @c{point}. Como se puede
    adivinar, se usa en una expresión @c{constrain-to-field}, igual que
    en @c{forward-sentence}.

#     The variable @c{fill-prefix-regexp} is set to the value returned by
#     evaluating the following list:
    La variable @c{fill-prefix-regexp} se establece con el valor devuelto de
    evaluar la siguiente lista:

#     ..src > elisp
#       (and fill-prefix
#            (not (equal fill-prefix ""))
#            (not paragraph-ignore-fill-prefix)
#            (regexp-quote fill-prefix))
#     < src..
    ..src > elisp
      (and fill-prefix
           (not (equal fill-prefix ""))
           (not paragraph-ignore-fill-prefix)
           (regexp-quote fill-prefix))
    < src..

#     This is an expression whose first element is the @c{and} special form.
    Esta es una expresión cuyo primer elemento es la forma especial @c{and}.

#     As we learned earlier (see Section @l{#The @c{kill-new} function}), the
#     @c{and} special form evaluates each of its arguments until one of the
#     arguments returns a value of @c{nil}, in which case the @c{and}
#     expression returns @c{nil}; however, if none of the arguments returns a
#     value of @c{nil}, the value resulting from evaluating the last argument
#     is returned.  (Since such a value is not @c{nil}, it is considered true
#     in Lisp.)  In other words, an @c{and} expression returns a true value
#     only if all its arguments are true.
    Como aprendimos anteriormente (Sección @l(#La función @c{kill-new})), la
    forma especial @c{and} evalúa cada uno de sus argumentos hasta uno de los
    argumentos devuelve un valor @c{nil}, en cuyo caso la expresión @c{and}
    devuelve @c{nil}; sin embargo, si ninguno de los argumentos devuelve un
    valor @c{nil}, se devuelve el valor resultante de evaluar el último
    argumento. (Puesto que tal valor no es @c{nil}, se considera verdadero en
    Lisp.) En otras palabras, una expresión @c{and} devuelve un valor verdadero
    solo si todos sus argumentos son verdaderos.

#     In this case, the variable @c{fill-prefix-regexp} is bound to a
#     non-@c{nil} value only if the following four expressions produce a true
#     (i.e., a non-@c{nil}) value when they are evaluated; otherwise,
#     @c{fill-prefix-regexp} is bound to @c{nil}.
    En este caso, la variable @c{fill-prefix-regexp} se vincula a un valor no
    @c{nil} solo si las cuatro expresiones siguientes producen un valor
    verdadero (es decir, un valor no @c{nil}) cuando se evalúan; de lo
    contrario, la variable @c{fill-prefix-regexp} se vincula a @c{nil}.

#     - @c(fill-prefix) ::
    - @c(fill-prefix) ::

#       When this variable is evaluated, the value of the fill prefix, if any,
#       is returned. If there is no fill prefix, this variable returns
#       @c{nil}.
      Cuando se evalua esta variable, se devuelve el valor del prefijo de
      relleno, si lo hay. Si no hay ningun prefijo relleno, esta variable devuelve
      @c{nil}.

#     - @c[(not (equal fill-prefix "")] ::
    - @c[(not (equal fill-prefix "")] ::

#       This expression checks whether an existing fill prefix is an empty
#       string, that is, a string with no characters in it. An empty string is
#       not a useful fill prefix.
      Esta expresión comprueba si un prefijo de relleno existente es una cadena
      vacía, es decir, una cadena sin caracteres. Una cadena vacía no es
      un prefijo de relleno útil.

#     - @c[(not paragraph-ignore-fill-prefix)] ::
    - @c[(not paragraph-ignore-fill-prefix)] ::

#       This expression returns @c{nil} if the variable
#       @c{paragraph-ignore-fill-prefix} has been turned on by being set to a
#       true value such as @c{t}.
      Esta expresión devuelve @c{nil} si la variable
      @c{paragraph-ignore-fill-prefix} ha sido activada al asignarle un valor
      verdadero como @c{t}.

#     - @c[(regexp-quote fill-prefix)] ::
    - @c[(regexp-quote fill-prefix)] ::

#       This is the last argument to the @c{and} special form. If all the
#       arguments to the @c{and} are true, the value resulting from evaluating
#       this expression will be returned by the @c{and} expression and bound to
#       the variable @c{fill-prefix-regexp},
      Este es el último argumento pasado a la forma especial @c{and}. Si todos
      los argumentos de @c{and} son verdaderos, el valor resultante de
      evaluar esta expresión será devuelto por la expresión @c{and} y
      asociado a la variable @c{fill-prefix-regexp},


#     The result of evaluating this @c{and} expression successfully is that
#     @c{fill-prefix-regexp} will be bound to the value of @c{fill-prefix} as
#     modified by the @c{regexp-quote} function. What @c{regexp-quote} does is
#     read a string and return a regular expression that will exactly match the
#     string and match nothing else. This means that @c{fill-prefix-regexp}
#     will be set to a value that will exactly match the fill prefix if the
#     fill prefix exists. Otherwise, the variable will be set to @c{nil}.
    El resultado de evaluar esta expresión @c{and} con éxito es que
    @c{fill-prefix-regexp} sera ligada al valor de @c{fill-prefix} como fué
    modificado por la función @c{regexp-quote}. Lo que @c{regexp-quote} hace es
    leer una cadena y devolver la expresión regular que coincida exactamente con
    la cadena y nada más. Esto significa que el valor de @c{fill-prefix-regexp} será
    asignado a un valor que coincida exactamente con el prefijo si existe. De lo
    contrario, la variable sera ligada a @c{nil}.

#     The next two local variables in the @c{let*} expression are designed to
#     remove instances of @'c{^} from @c{parstart} and @c{parsep}, the local
#     variables which indicate the paragraph start and the paragraph separator.
#     The next expression sets @c{parsep} again. That is to handle fill
#     prefixes.
    Las siguientes dos variables locales en la expresión @c{let*} están
    diseñadas para eliminar instancias de @'c{^} de @c{parstart} y @c{parsep},
    las variables locales que indican el inicio del párrafo y el separador de
    párrafos. La siguiente expresión define @c{parsep} de nuevo. Esto es para
    manejar prefijos de relleno.

#     This is the setting that requires the definition call @c{let*} rather
#     than @c{let}. The true-or-false-test for the @c{if} depends on whether
#     the variable @c{fill-prefix-regexp} evaluates to @c{nil} or some other
#     value.
    Esta es la configuracion que requiere la llamada de la definición
    @c{let*} en lugar de @c{let}. La prueba-verdadero-o-falso del @c{if} depende
    de si la variable @c{fill-prefix-regexp} se evalúa a @c{nil} o algún otro
    valor.

#     If @c{fill-prefix-regexp} does not have a value, Emacs evaluates the
#     else-part of the @c{if} expression and binds @c{parsep} to its local
#     value.  (@c{parsep} is a regular expression that matches what separates
#     paragraphs.)
    Si @c{fill-prefix-regexp} no tiene un valor, Emacs evalúa la parte-else
    de la expresión @c{if} y vinculara @c{parsep} a su valor local. (@c{parsep}
    es una expresión regular que coincide con la separacion de párrafos.)

#     But if @c{fill-prefix-regexp} does have a value, Emacs evaluates the
#     then-part of the @c{if} expression and binds @c{parsep} to a regular
#     expression that includes the @c{fill-prefix-regexp} as part of the
#     pattern.
    Pero si @c{fill-prefix-regexp} tiene un valor, Emacs evalúa la parte-then
    de la expresión @c{if} y enlaza @c{parsep} a una expresión regular que
    incluye @c{fill-prefix-regexp} como parte del patrón.

#     Specifically, @c{parsep} is set to the original value of the paragraph
#     separate regular expression concatenated with an alternative expression
#     that consists of the @c{fill-prefix-regexp} followed by optional
#     whitespace to the end of the line. (The whitespace is defined by @"c{[ \t]*$}.)
#     The @'{\\|} defines this portion of the regexp as an alternative to @c{parsep}.
    Específicamente, @c{parsep} se asigna al valor original del separador del
    párrafo, la expresión regular concatenada con una expresión alternativa que
    consiste en @c{fill-prefix-regexp} seguido por espacios en blanco opcionales
    halta el fin de la línea. (El espacio en blanco se define con @"c{[ \t]*$}.)
    El @'{\\|} define esta porción de la regexp como una alternativa a @c{parsep}.

#     According to a comment in the code, the next local variable,
#     @c{sp-parstart}, is used for searching, and then the final two, @c{start}
#     and @c{found-start}, are set to @c{nil}.
    De acuerdo a un comentario en el código, la siguiente variable local,
    @c{sp-parstart}, se utiliza para la busqueda, y luego los dos finales,
    @c{start} y @c{found-start}, se asignan a @c{nil}.

#     Now we get into the body of the @c{let*}. The first part of the body of
#     the @c{let*} deals with the case when the function is given a negative
#     argument and is therefore moving backwards. We will skip this section.
    Ahora entramos en el cuerpo del @c{let*}. La primera parte del cuerpo del
    @c{let*} trata el caso cuando la función recibe un argumento negativo y por
    lo tanto se mueve hacia atrás. Omitiremos esta sección.

# *** The forward motion @c{while} loop
*** El bucle @c{while} hacia adelante

#     The second part of the body of the @c{let*} deals with forward motion.
#     It is a @c{while} loop that repeats itself so long as the value of
#     @c{arg} is greater than zero. In the most common use of the function,
#     the value of the argument is 1, so the body of the @c{while} loop is
#     evaluated exactly once, and the cursor moves forward one paragraph.
    La segunda parte del cuerpo del @c{let*} se ocupa del movimiento hacia
    adelante. Es un bucle @c{while} que se repite mientras el valor de @c{arg}
    sea mayor a cero. En el uso más común de la función el valor del argumento es
    1, por lo que el cuerpo del bucle @c{while} se evalúa exactamente una vez, y
    el cursor avanza hacia adelante un párrafo.

#     This part handles three situations: when point is between paragraphs,
#     when there is a fill prefix and when there is no fill prefix.
    Esta parte maneja tres situaciones: cuando el punto está entre párrafos,
    cuando hay un prefijo de relleno y cuando no hay un prefijo de relleno.

#     The @c{while} loop looks like this:
    El bucle @c{while} se ve así:

#     ..src > elisp
    ..src > elisp
#       ;; going forwards and not at the end of the buffer
      ;; avanza hacia adelante y no al final del búfer
#       (while (and (> arg 0) (not (eobp)))
      (while (and (> arg 0) (not (eobp)))

#         ;; between paragraphs
#         ;; Move forward over separator lines...
        ;; entre párrafos
        ;; Avanzar sobre lineas de separacion...
#         (while (and (not (eobp))
#                     (progn (move-to-left-margin) (not (eobp)))
#                     (looking-at parsep))
#           (forward-line 1))
        (while (and (not (eobp))
                    (progn (move-to-left-margin) (not (eobp)))
                    (looking-at parsep))
          (forward-line 1))
#         ;;  This decrements the loop
        ;;  Esto decrementa el bucle
#         (unless (eobp) (setq arg (1- arg)))
        (unless (eobp) (setq arg (1- arg)))
#         ;; ... and one more line.
        ;; ... y una línea más
#         (forward-line 1)
        (forward-line 1)

#         (if fill-prefix-regexp
        (if fill-prefix-regexp
#             ;; There is a fill prefix; it overrides parstart;
#             ;; we go forward line by line
            ;; Hay un prefijo de relleno; sobreescribe parstart;
            ;; avanzamos línea a línea
#             (while (and (not (eobp))
#                         (progn (move-to-left-margin) (not (eobp)))
#                         (not (looking-at parsep))
#                         (looking-at fill-prefix-regexp))
#               (forward-line 1))
            (while (and (not (eobp))
                        (progn (move-to-left-margin) (not (eobp)))
                        (not (looking-at parsep))
                        (looking-at fill-prefix-regexp))
              (forward-line 1))

#           ;; There is no fill prefix;
#           ;; we go forward character by character
          ;; No hay prefijo de relleno;
          ;; avanzamos caracter por caracter
#           (while (and (re-search-forward sp-parstart nil 1)
#                       (progn (setq start (match-beginning 0))
#                              (goto-char start)
#                              (not (eobp)))
#                       (progn (move-to-left-margin)
#                              (not (looking-at parsep)))
#                       (or (not (looking-at parstart))
#                           (and use-hard-newlines
#                                (not (get-text-property (1- start) 'hard)))))
#             (forward-char 1))
          (while (and (re-search-forward sp-parstart nil 1)
                      (progn (setq start (match-beginning 0))
                             (goto-char start)
                             (not (eobp)))
                      (progn (move-to-left-margin)
                             (not (looking-at parsep)))
                      (or (not (looking-at parstart))
                          (and use-hard-newlines
                               (not (get-text-property (1- start) 'hard)))))
            (forward-char 1))

#           ;; and if there is no fill prefix and if we are not at the end,
#           ;;     go to whatever was found in the regular expression search
#           ;;     for sp-parstart
          ;; y si no hay prefijo de relleno y si no estamos al final
          ;; ir a lo que se encontro en la búsqueda de expresiones regulares
          ;; para sp-parstart
#           (if (< (point) (point-max))
#               (goto-char start))))
          (if (< (point) (point-max))
              (goto-char start))))
#     < src..
    < src..

#     We can see that this is a decrementing counter @c{while} loop, using the
#     expression @c{(setq arg (1- arg))} as the decrementer. That expression
#     is not far from the @c{while}, but is hidden in another Lisp macro, an
#     @c{unless} macro. Unless we are at the end of the buffer––that is what
#     the @c{eobp} function determines; it is an abbreviation of @'{End Of
#     Buffer P}––we decrease the value of @c{arg} by one.
    Podemos ver que se trata de un contador de decremento @c{while}, usando la
    expresión @c{(setq arg (1- arg))} como decrementador. Esta expresión no está
    lejos del @c{while}, pero está oculta en otra macro Lisp, una macro
    @c{unless}. A menos que estemos al final del búfer––eso es lo que determina
    la función @c{eobp}; es una abreviación de @'{End of Buffer P}––disminuimos
    el valor de @c{arg} por uno.

#     (If we are at the end of the buffer, we cannot go forward any more and
#     the next loop of the @c{while} expression will test false since the test
#     is an @c{and} with @c{(not (eobp))}. The @c{not} function means exactly
#     as you expect; it is another name for @c{null}, a function that returns
#     true when its argument is false.)
    (Si estamos al fin del búfer, ya no podemos avanzar mas y el siguiente bucle
    de la expresión @c{while} sera falso ya que la prueba es un @c{and} con
    @c{(not (eobp))}. La función @c{not} significa exactamente lo que se espera;
    es otro nombre para @c{null}, una función que devuelve verdadero cuando su
    argumento es falso.)

#     Interestingly, the loop count is not decremented until we leave the space
#     between paragraphs, unless we come to the end of buffer or stop seeing
#     the local value of the paragraph separator.
    Curiosamento, el contador del bucle no disminuye hasta que dejamos el
    espacio entre párrafos, a menos que lleguemos al fin del búfer o dejemos de
    ver el valor local del separador del párrafo.

#     That second @c{while} also has a @c{(move-to-left-margin)} expression.
#     The function is self-explanatory. It is inside a @c{progn} expression
#     and not the last element of its body, so it is only invoked for its side
#     effect, which is to move point to the left margin of the current line.
    El segundo @c{while} también tiene una expresión @c{(move-to-left-margin)}.
    La función es autoexplicativa. Está dentro de una expresión @c{progn} y no
    es el último elemento de su cuerpo, por lo que solo se invoca por su efecto
    secundario, que es mover el punto al margen izquierdo de la línea actual.

#     The @c{looking-at} function is also self-explanatory; it returns true if
#     the text after point matches the regular expression given as its
#     argument.
    La función @c{looking-at} también es auto-explicativa; devuelve
    verdadero si el texto después del punto coincide con la expresión regular dada
    como su argumento.

#     The rest of the body of the loop looks difficult at first, but makes
#     sense as you come to understand it.
    El resto del cuerpo del bucle parece complejo al principio, pero tiene
    sentido a medida que se llega a entender.

#     First consider what happens if there is a fill prefix:
    Primero considera lo que sucede si hay un prefijo de relleno:

#     ..src > elisp
#       (if fill-prefix-regexp
#           ;; There is a fill prefix; it overrides parstart;
#           ;; we go forward line by line
#           (while (and (not (eobp))
#                       (progn (move-to-left-margin) (not (eobp)))
#                       (not (looking-at parsep))
#                       (looking-at fill-prefix-regexp))
#             (forward-line 1))
#     < src..
    ..src > elisp
      (if fill-prefix-regexp
          ;; Hay un prefijo de relleno; sobreescribe parstart;
          ;; avanzamos línea a línea
          (while (and (not (eobp))
                      (progn (move-to-left-margin) (not (eobp)))
                      (not (looking-at parsep))
                      (looking-at fill-prefix-regexp))
            (forward-line 1))
    < src..

#     This expression moves point forward line by line so long as four
#     conditions are true:
    Esta expresión mueve el punto hacia adelante línea por línea siempre y
    cuando se cumplan cuatro condiciones:

#     1. Point is not at the end of the buffer.
    1. El punto no está al final del búfer.

#     2. We can move to the left margin of the text and are not at the end of
#        the buffer.
    2. Podemos movernos al margen izquierdo del texto y no estamos al fin del
       búfer.

#     3. The text following point does not separate paragraphs.
    3. El texto siguiente al punto no separa los párrafos.

#     4. The pattern following point is the fill prefix regular expression.
    4. El patrón que sigue al punto es la expresión regular del prefijo de relleno.


#     The last condition may be puzzling, until you remember that point was
#     moved to the beginning of the line early in the @c{forward-paragraph}
#     function. This means that if the text has a fill prefix, the
#     @c{looking-at} function will see it.
    La última condición puede ser un puzzle, hasta que se recuerde qué el punto
    fue movido al principio de la línea anteriormente en la función
    @c{forward-paragraph}. Esto significa que si el texto tiene un prefijo
    de relleno, la función @c{looking-at} lo verá.

#     Consider what happens when there is no fill prefix.
    Considera qué ocurre cuando no hay un prefijo lleno.

#     ..src > elisp
#       (while (and (re-search-forward sp-parstart nil 1)
#                   (progn (setq start (match-beginning 0))
#                          (goto-char start)
#                          (not (eobp)))
#                   (progn (move-to-left-margin)
#                          (not (looking-at parsep)))
#                   (or (not (looking-at parstart))
#                       (and use-hard-newlines
#                            (not (get-text-property (1- start) 'hard)))))
#         (forward-char 1))
#     < src..
    ..src > elisp
      (while (and (re-search-forward sp-parstart nil 1)
                  (progn (setq start (match-beginning 0))
                         (goto-char start)
                         (not (eobp)))
                  (progn (move-to-left-margin)
                         (not (looking-at parsep)))
                  (or (not (looking-at parstart))
                      (and use-hard-newlines
                           (not (get-text-property (1- start) 'hard)))))
        (forward-char 1))
    < src..

#     This @c{while} loop has us searching forward for @c{sp-parstart}, which
#     is the combination of possible whitespace with a the local value of the
#     start of a paragraph or of a paragraph separator.  (The latter two are
#     within an expression starting @c{\(?:} so that they are not referenced by
#     the @c{match-beginning} function.)
    El bucle @c{while} nos lleva a la busqueda de @c{sp-parstart}, que es la
    combinación de posibles espacios en blanco con el valor local del inicio de
    un párrafo o de un separador de párrafos. (Los dos últimos se encuentran
    dentro de una expresión que comienza con @c{\(?:} así que no están
    referenciados por la función @c{match-beginning}.)

#     The two expressions,
    Las dos expresiones,

#     ..src > elisp
#       (setq start (match-beginning 0))
#       (goto-char start)
#     < src..
    ..src > elisp
      (setq start (match-beginning 0))
      (goto-char start)
    < src..

#     mean go to the start of the text matched by the regular expression
#     search.
    significan ir al comienzo del texto localizado con la expresión regular.

#     The @c{(match-beginning 0)} expression is new. It returns a number
#     specifying the location of the start of the text that was matched by the
#     last search.
    La expresión @c{(match-beginning 0)} es nueva. Devuelve un número que
    especifica la ubicacion del inicio del texto que coincidio con la última
    búsqueda.

#     The @c{match-beginning} function is used here because of a characteristic
#     of a forward search: a successful forward search, regardless of whether
#     it is a plain search or a regular expression search, moves point to the
#     end of the text that is found. In this case, a successful search moves
#     point to the end of the pattern for @c{sp-parstart}.
    La función @c{match-beginning} se utiliza aquí debido a una característica
    de la búsqueda hacia adelante: una búsqueda exitosa hacia adelante,
    independientemente de si se trata de una búsqueda simple o de una con expresiónes
    regulares, mueve el punto al fin del texto que encuentra. En este caso,
    una búsqueda exitosa mueve el punto al fin del patrón de @c{sp-parstart}.

#     However, we want to put point at the end of the current paragraph, not
#     somewhere else. Indeed, since the search possibly includes the paragraph
#     separator, point may end up at the beginning of the next one unless we
#     use an expression that includes @c{match-beginning}.
    Sin embargo, queremos poner el punto al fin del actual párrafo, no en algún
    otro lugar. De hecho, dado que la búsqueda posiblemente incluye el separador
    de párrafos, el punto puede finalizar al principio del siguiente a menos que
    utilicemos una expresión que incluya @c{match-beginning}.

#     When given an argument of 0, @c{match-beginning} returns the position
#     that is the start of the text matched by the most recent search. In this
#     case, the most recent search looks for @c{sp-parstart}. The
#     @c{(match-beginning 0)} expression returns the beginning position of that
#     pattern, rather than the end position of that pattern.
    Cuando se le da un argumento de 0, @c{match-beginning} devuelve la posición
    de inicio del texto coincidente con la búsqueda más reciente. En este caso,
    la búsqueda más reciente de @c{sp-parstart}. La expresión
    @c{(match-beginning 0)} devuelve la posición inicial de ese patrón, en
    lugar de la posición final.

#     (Incidentally, when passed a positive number as an argument, the
#     @c{match-beginning} function returns the location of point at that
#     parenthesized expression in the last search unless that parenthesized
#     expression begins with @c{\(?:}. I don't know why @c{\(?:} appears here
#     since the argument is 0.)
    (Incidentalmente, cuando se pasa un número positivo como argumento, la
    función @c{match-beginning} devuelve la ubicacion del punto de la
    expresión con paréntesis en la última búsqueda a menos que la expresión con
    paréntesis empiece con @c{\(?:}. No sé porque @c{\(?:} aparece aquí, ya que
    el argumento es 0.)

#     The last expression when there is no fill prefix is
    La última expresión cuando no hay prefijo de relleno es

#     ..src > elisp
#       (if (< (point) (point-max))
#           (goto-char start))))
#     < src..
    ..src > elisp
      (if (< (point) (point-max))
          (goto-char start))))
    < src..

#     This says that if there is no fill prefix and if we are not at the end,
#     point should move to the beginning of whatever was found by the regular
#     expression search for @c{sp-parstart}.
    Esto dice que si no hay un prefijo de relleno y no estamos al final, el punto
    deberia moverse al principio de lo que sea que sea haya encontrado al buscar la
    expresión regular de @c{sp-parstart}.

#     The full definition for the @c{forward-paragraph} function not only
#     includes code for going forwards, but also code for going backwards.
    La definición completa de la función @c{forward-paragraph} no solo
    incluye código para avanzar, sino también código para retroceder.

#     If you are reading this inside of GNU Emacs and you want to see the whole
#     function, you can type @k{C-h f} @%c(describe-function) and the name of
#     the function. This gives you the function documentation and the name of
#     the library containing the function's source. Place point over the name
#     of the library and press the @c(RET) key; you will be taken directly to the
#     source.  (Be sure to install your sources!  Without them, you are like a
#     person who tries to drive a car with his eyes shut!)
    Si estás leyendo esto dentro de GNU Emacs y quieres ver la función
    completa, puedes escribir @k{C-h f} @%c(describe-function) y el nombre
    de la función. Esto proporciona la documentación de función y el nombre de la
    librería que contiene el codigo fuente de la función. Coloca el punto sobre
    el nombre de la librería y presionar la tecla @k(RET); serás llevado
    directamente al codigo fuente. (¡Asegúrate de instalar el codigo fuente! ¡Sin
    el, eres como una persona que intenta conducir un coche con los ojos
    cerrados!)

# ** Create Your Own @f{TAGS} File
** Crea tu propio fichero @f{TAGS}

#    Besides @k{C-h f} @%c(describe-function), another way to see the source
#    of a function is to type @k{M-.} @%c(find-tag) and the name of the
#    function when prompted for it. This is a good habit to get into. The
#    @k{M-.} @%c(find-tag) command takes you directly to the source for a
#    function, variable, or node. The function depends on tags tables to tell
#    it where to go.
   Ademas de @k{C-h f} @%c(describe-function), otra forma de ver el codigo de
   una función es escribir @k{M-.} @%c(find-tag) y el nombre de la función
   cuando se solicite. Es un buen hábito para obtenerlo. El comando @k{M-.}
   @%c(find-tag) te lleva directamente al codigo de una función, variable, o
   nodo. La función depende de tablas de etiquetas para saber donde ir.

#    If the @c{find-tag} function first asks you for the name of a @f{TAGS}
#    table, give it the name of a @f{TAGS} file such as
#    @f{/usr/local/src/emacs/src/TAGS}. (The exact path to your @f{TAGS} file
#    depends on how your copy of Emacs was installed. I just told you the
#    location that provides both my C and my Emacs Lisp sources.)
   Si la función @c{find-tag} pregunta primero por el nombre de una tabla
   @f{TAGS}, dale el nombre de un fichero @f{TAGS} como
   @f{/usr/local/src/emacs/src/TAGS}. (La ruta exacta a tu fichero @f{TAGS}
   depende de cómo instalaste tu copia de Emacs. Yo proporcione la localización
   tanto de mi codigo fuente de C, como de Emacs Lisp.)

#    You can also create your own @f{TAGS} file for directories that lack one.
   Tambien puedes crear tu propio fichero @f{TAGS} para directorios que
   carecen de uno.

#    You often need to build and install tags tables yourself. They are not
#    built automatically. A tags table is called a @f{TAGS} file; the name is
#    in upper case letters.
   Con frecuencia se necesita construir e instalar tablas de etiquetas por
   cuenta propia. No se construiyen automáticamente. Una tabla de etiquetas
   es un fichero que lleva por nombre @f{TAGS}; el nombre esta en letras mayúsculas.

#    You can create a @f{TAGS} file by calling the @c{etags} program that comes
#    as a part of the Emacs distribution. Usually, @c{etags} is compiled and
#    installed when Emacs is built.  (@c{etags} is not an Emacs Lisp function
#    or a part of Emacs; it is a C program.)
   Puedes crear un fichero @f{TAGS} llamando al programa @c{etags} que
   viene como parte de la distribución de Emacs. Por lo general, @c{etags} se
   compila e instala cuando se construye Emacs. (@c{etags} no es una
   función Lisp ni parte de Emacs; es un programa C.)

#    To create a @f{TAGS} file, first switch to the directory in which you want
#    to create the file. In Emacs you can do this with the @k{M-x cd} command,
#    or by visiting a file in the directory, or by listing the directory with
#    @k{C-x d} @%c(dired). Then run the @c(compile) command, with @${etags *.el}
#    as the command to execute
   Para crear el fichero @f{TAGS}, primero cambia al directorio en el que
   deseas crear el fichero. En Emacs se puede hacer esto con el comando
   @k{M-x cd}, o visitando un fichero en el directorio, o listando el
   directorio con @k{C-x d} @%c(dired). A continuacion, ejecuta el comando
   @c(compile), con @${etags *.el} como el comando a ejecutar

#    ..example >
#      M-x compile RET etags *.el RET
#    < example..
   ..example >
     M-x compile RET etags *.el RET
   < example..

#    to create a @f{TAGS} file for Emacs Lisp.
   para crear un fichero @f{TAGS} para Emacs Lisp.

#    For example, if you have a large number of files in your @f{~/emacs}
#    directory, as I do––I have 137 @f{.el} files in it, of which I load
#    12––you can create a @f{TAGS} file for the Emacs Lisp files in that
#    directory.
   Por ejemplo, si se tiene un gran número de ficheros en el directorio
   @f{~/emacs}, como en mi caso––yo tengo 137 ficheros @f{.el}, de los cuales cargo
   12––se puede crear un fichero @f{TAGS} para los ficheros Emacs Lisp en
   ese directorio.

#    The @${etags} program takes all the usual shell ‘wildcards’. For example,
#    if you have two directories for which you want a single @f{TAGS} file,
#    type @c{etags *.el ../elisp/*.el}, where @f{../elisp/} is the second
#    directory:
   El programa @${etags} recive todos los ‘comodines’ usuales del shell. Por
   ejemplo, si tienes dos directorios para los que deseas un unico fichero
   @f{TAGS}, ingresa @c{etags *.el ../elisp/*.el}, donde @f{../elisp/} es el
   segundo directorio:

#    ..example >
#      M-x compile RET etags *.el ../elisp/*.el RET
#    < example..
   ..example >
     M-x compile RET etags *.el ../elisp/*.el RET
   < example..

#    Type
   Ingresa

#    ..example >
#      M-x compile RET etags --help RET
#    < example..
   ..example >
     M-x compile RET etags --help RET
   < example..

#    to see a list of the options accepted by @${etags} as well as a list of
#    supported languages.
   para ver una lista de las opciones aceptadas por @${etags} asi como
   una lista de lenguajes soportados.

#    The @${etags} program handles more than 20 languages, including Emacs
#    Lisp, Common Lisp, Scheme, C, C++, Ada, Fortran, HTML, Java, LaTeX,
#    Pascal, Perl, PostScript, Python, TeX, Texinfo, makefiles, and most
#    assemblers. The program has no switches for specifying the language; it
#    recognizes the language in an input file according to its file name and
#    contents.
   El programa @${etags} maneja más de 20 lenguajes, incluyendo Emacs Lisp,
   Common Lisp, Scheme, C, C++, Ada, Fortran, HTML, Java, LaTeX, Pascal,
   Perl, Postscript, Python, TeX, Texinfo, makefiles, y la mayoría de
   ensambladores. El programa no tiene interruptores para especificar el lenguaje;
   reconoce el lenguaje en un fichero de entrada segun su nombre y contenido.

#    @${etags} is very helpful when you are writing code yourself and want to
#    refer back to functions you have already written. Just run @${etags}
#    again at intervals as you write new functions, so they become part of the
#    @f{TAGS} file.
   @${etags} es muy útil cuando estas escribiendo código y quieres referirte a
   funciones que ya has escrito. Simplemente ejecuta de nuevo @${etags} a medida
   que escribas nuevas funciones, para que formen parte del fichero @f{TAGS}.

#    If you think an appropriate @f{TAGS} file already exists for what you
#    want, but do not know where it is, you can use the @${locate} program to
#    attempt to find it.
   Si crees que ya existe un fichero @f{TAGS} apropiado para lo que buscas, pero
   no conoces donde está, puedes usar el programa @${locate} para intentar
   encontrarlo.

#    Type @k{M-x locate RET TAGS RET} and Emacs will list for you the
#    full path names of all your @f{TAGS} files. On my system, this command
#    lists 34 @f{TAGS} files. On the other hand, a ‘plain vanilla’ system I
#    recently installed did not contain any @f{TAGS} files.
   Escribe @k{M-x locate RET TAGS RET} y Emacs listará los nombres de ruta
   completos de todos tus ficheros @f{TAGS}. En mi sistema, este comando muestra
   34 fichero @f{TAGS}. Por otra parte, un sistema ‘vainilla’ instalado
   recientemente no contenía ningun fichero @f{TAGS}.

#    If the tags table you want has been created, you can use the @c{M-x
#    visit-tags-table} command to specify it. Otherwise, you will need to
#    create the tag table yourself and then use @c{M-x visit-tags-table}.
   Si la tabla de etiquetas que buscas ya ha sido creada, puedes utilizar el
   comando @c{M-x visit-tags-table} para especificarla. De lo contrario, tendras
   que crear la tabla de etiquetas por tí mismo y luego utilizar @c{M-x
   visit-tags-table}.

# *** Building Tags in the Emacs sources
*** Construyendo Etiquetas en el codigo de Emacs

#     The GNU Emacs sources come with a @f{Makefile} that contains a
#     sophisticated @${etags} command that creates, collects, and merges tags
#     tables from all over the Emacs sources and puts the information into one
#     @f{TAGS} file in the @f{src/} directory. (The @f{src/} directory is below
#     the top level of your Emacs directory.)
    El codigo fuente de GNU Emacs vienen con un @f{Makefile} que contiene un comando
    @${etags} sofisticado que crea, recoge, y une tablas de etiquetas con
    todo el codigo de Emacs y coloca la información dentro de un fichero
    @f{TAGS} en el directorio @f{src/}. (El directorio @f{src/} está debajo
    del nivel superior de tu directorio Emacs.)

#     To build this @f{TAGS} file, go to the top level of your Emacs source
#     directory and run the compile command @${make tags}:
    Para construir este fichero @f{TAGS}, debes ir al nivel superior del directorio
    con el codigo fuente de Emacs y ejecutar el comando de compilacion @${make
    tags}:

#     ..example >
#       M-x compile RET make tags RET
#     < example..
    ..example >
      M-x compile RET make tags RET
    < example..

#     (The @${make tags} command works well with the GNU Emacs sources, as well
#     as with some other source packages.)
    (El comando @${make tags} funciona bien con las fuentes de GNU Emacs, asi
    como con algunos otros paquetes de codigo fuente.)

#     For more information, see Section @l{emacs.html#Tags Tables<>Tag Tables} in
#     @e(The GNU Emacs Manual).
    Para más información, mira @l{emacs.html#Tags Tables<>Tablas de Etiquetas} en @e(El
    Manual de GNU Emacs).

# ** Review
** Repaso

#    Here is a brief summary of some recently introduced functions.
   Aquí hay un breve resumen de algunas de las funciones introducidas recientemente.

#    - @c(while) ::
   - @c(while) ::

#      Repeatedly evaluate the body of the expression so long as the first
#      element of the body tests true. Then return @c{nil}.  (The expression
#      is evaluated only for its side effects.)
     Evalúa repetidamente el cuerpo de la expresión simpre y cuando el primer
     elemento del cuerpo sea verdadero. Despues devuelve @c{nil}. (La
     expresión se evalua solo por sus efectos secundarios.)

#      For example:
     Por ejemplo:

#      ..srci > elisp
#        > (let ((foo 2))
#        ^   (while (> foo 0)
#        ^     (insert (format "foo is %d.\n" foo))
#        ^     (setq foo (1- foo))))
#        foo is 2.
#        foo is 1.
#        nil
#      < srci..
     ..srci > elisp
       > (let ((foo 2))
       ^   (while (> foo 0)
       ^     (insert (format "foo es %d.\n" foo))
       ^     (setq foo (1- foo))))
       foo es 2.
       foo es 1.
       nil
     < srci..

#      (The @c{insert} function inserts its arguments at point; the @c{format}
#      function returns a string formatted from its arguments the way
#      @c{message} formats its arguments; @c{\n} produces a new line.)
     (La función @c{insert} inserta sus argumentos en el punto; la función
     @c{format} devuelve una cadena formateada a partir de sus argumentos de la
     misma manera en que @c{message} formatea sus argumentos; @c{\n} produce una nueva
     línea.)

#    - @c(re-search-forward) ::
   - @c(re-search-forward) ::

#      Search for a pattern, and if the pattern is found, move point to rest
#      just after it.
     Busca un patrón, y si se encuentra, mueve el punto al final de la coincidencia.

#      Takes four arguments, like @c{search-forward}:
     Igual que @c{search-forward}, toma cuatro argumentos:

#      1. A regular expression that specifies the pattern to search for.
#         (Remember to put quotation marks around this argument!)
     1. Una expresión regular que especifica el patrón a buscar. (¡Recuerda
        poner comillas alrededor de este argumento!)

#      2. Optionally, the limit of the search.
     2. Opcionalmente, el límite de la búsqueda.

#      3. Optionally, what to do if the search fails, return @c{nil} or an
#         error message.
     3. Opcionalmente, que hacer si la búsqueda falla, devuelve @c{nil} o un
        mensaje de error.

#      4. Optionally, how many times to repeat the search; if negative, the
#         search goes backwards.
     4. Opcionalmente, cuántas veces se puede repetir la búsqueda; si es
        negativa, la búsqueda va hacia atrás.

#    - @c(let*) ::
   - @c(let*) ::

#      Bind some variables locally to particular values, and then evaluate the
#      remaining arguments, returning the value of the last one. While binding
#      the local variables, use the local values of variables bound earlier, if
#      any.
     Asocia algunas variables localmente a valores particulares, y luego evalúa
     los argumentos restantes, devolviendo el valor del último. Al asociar las
     variables locales, se pueden usan los valores locales de variables
     declaradas anteriormente.

#      For example:
     Por ejemplo:

#      ..srci > elisp
#        > (let* ((foo 7)
#        ^        (bar (* 3 foo)))
#        ^   (message "`bar' is %d." bar))
#        ‘bar’ is 21.
#      < srci..
     ..srci > elisp
       > (let* ((foo 7)
       ^        (bar (* 3 foo)))
       ^   (message "`bar' es %d." bar))
       ‘bar’ es 21.
     < srci..

#    - @c(match-beginning) ::
   - @c(match-beginning) ::

#      Return the position of the start of the text found by the last regular
#      expression search.
     Devuelve la posición del inicio del texto encontrado por la última
     búsqueda de una expresión regular.

#    - @c(looking-at) ::
   - @c(looking-at) ::

#      Return @c{t} for true if the text after point matches the argument,
#      which should be a regular expression.
     Devuelve @c{t} por verdadero si el texto después del punto coincide con el
     argumento, que debería ser una expresión regular.

#    - @c(eobp) ::
   - @c(eobp) ::

#      Return @c{t} for true if point is at the end of the accessible part of a
#      buffer. The end of the accessible part is the end of the buffer if the
#      buffer is not narrowed; it is the end of the narrowed part if the buffer
#      is narrowed.
     Devuelve @c{t} por verdadero si el punto está al final de la parte
     accesible de un búfer. El final de la parte accesible es el final del
     búfer sin reduccion; es el final de la parte reducida en un búfer
     reducido.

# ** Exercises with @c{re-search-forward}
** Ejercicios con @c{re-search-forward}

#    - Write a function to search for a regular expression that matches two or
#      more blank lines in sequence.
   - Escribe una función para buscar una expresión regular que coincida con dos o más
     líneas en blanco consecutivas.

#    - Write a function to search for duplicated words, such as ‘the the’. See
#      Section @l{emacs.html#Regexps<>Syntax of Regular Expressions} in @e(The
#      GNU Emacs Manual), for information on how to write a regexp (a regular
#      expression) to match a string that is composed of two identical halves.
#      You can devise several regexps; some are better than others. The
#      function I use is described in an appendix, along with several regexps.
#      See Section @l{#Appendix A: The @c{the-the} Function}.
   - Escribe una función para buscar palabras duplicadas, como ‘el el’. Consulta la
     Seccion @l{emacs.html#Regexps<>Syntax of Regular Expressions} en @e(El Manual de GNU Emacs), para obtener
     información de cómo escribir una regexp (una expresión regular) para que
     coincida con una cadena compuesta de dos mitades idénticas. Puedes idear
     varias regexps; algunas son mejores que otras. La función que
     yo utilizo se describe en un apéndice, junto con varias regexps. Consulta la
     Seccion @l{#Apéndice A: La función @c{el-el}}.

# * Counting: Repetition and Regexps
* Conteo: repetición y regexps

#   Repetition and regular expression searches are powerful tools that you
#   often use when you write code in Emacs Lisp. This chapter illustrates the
#   use of regular expression searches through the construction of word count
#   commands using @c{while} loops and recursion.
  La repetición y la búsqueda de expresiones regulares son poderosas
  herramientas que con frecuencia se usan al escribir código en Emacs
  Lisp. Este capítulo ilustra el uso de búsqueda de expresiones regulares a
  través de la construcción de comandos de conteo de palabras usando bucles
  @c{while} y recursión.

#   The standard Emacs distribution contains functions for counting the number
#   of lines and words within a region.
  La distribución de Emacs estándar contiene una función para contar el
  número de líneas dentro de una región.

#   Certain types of writing ask you to count words. Thus, if you write an
#   essay, you may be limited to 800 words; if you write a novel, you may
#   discipline yourself to write 1000 words a day. It seems odd, but for a
#   long time, Emacs lacked a word count command. Perhaps people used Emacs
#   mostly for code or types of documentation that did not require word counts;
#   or perhaps they restricted themselves to the operating system word count
#   command, @${wc}. Alternatively, people may have followed the publishers'
#   convention and computed a word count by dividing the number of characters
#   in a document by five.
  Ciertos tipos de escritura piden el conteo de palabras. Por lo tanto, si
  escribes un ensayo, puedes limitarte a 800 palabras; si escribes una novela,
  puedes disciplinarte a escribir 1000 palabras al día. Parece extraño, pero
  durante mucho tiempo, a Emacs le faltó un comando para contar palabras. Quizás
  la gente usaba Emacs principalmente para codificar o documentar cosas que no
  requerian contar las palabras, o quizás se limitaban al comando de conteo de
  palabras del sistema operativo, @${wc}. Alternativamente, las personas pueden
  haber seguido la convención de las editoriales y calcular un conteo de palabras
  dividiendo el número de caracteres de un documento por cinco.

#   There are many ways to implement a command to count words. Here are some
#   examples, which you may wish to compare with the standard Emacs command,
#   @c{count-words-region}.
  Hay muchas maneras de implementar un comando para contar palabras. Aquí hay
  algunos ejemplos, que se puede comparar con el comando estándar de Emacs,
  @c{count-words-region}.

# ** The @c{count-words-example} Function
** La función @c{count-words-example}

#    A word count command could count words in a line, paragraph, region, or
#    buffer. What should the command cover?  You could design the command to
#    count the number of words in a complete buffer. However, the Emacs
#    tradition encourages flexibility––you may want to count words in just a
#    section, rather than all of a buffer. So it makes more sense to design
#    the command to count the number of words in a region. Once you have a
#    command to count words in a region, you can, if you wish, count words in a
#    whole buffer by marking it with @k{C-x h} @%c(mark-whole-buffer).
   Un comando de conteo de palabras podría contar palabras en una línea,
   párrafo, región, o búfer. ¿Qué debe cubrir el comando? Se podría diseñar el
   comando para contar el número de palabras en un búfer completo. Sin embargo,
   la tradición en Emacs fomenta la flexibilidad––se puede querer contar solo
   las palabras en una sección, en lugar de en todo un búfer. Así que tiene más
   sentido diseñar el comando para contar el número de palabras en una
   región. Una vez tienes un comando @c{count-words-region}, puedes, si lo
   deseas, contar palabras en un búfer completo marcándolo con @k{C-x h}
   @%c(mark-whole-buffer).

#    Clearly, counting words is a repetitive act: starting from the beginning
#    of the region, you count the first word, then the second word, then the
#    third word, and so on, until you reach the end of the region. This means
#    that word counting is ideally suited to recursion or to a @c{while} loop.
   Es evidente que contar palabras es un acto repetitivo: a partir del
   principio de la región, se cuenta la primer palabra, luego la segunda,
   despues la tercera, y así sucesivamente, hasta llegar al fin de la
   región. Esto significa que el conteo de palabras se ajusta idealmente a la
   recursión o a un bucle @c{while}.

#    First, we will implement the word count command with a @c{while} loop,
#    then with recursion. The command will, of course, be interactive.
   Primero, implementaremos el comando para contar palabras con un bucle
   @c{while}, luego con recursión. El comando sera, por supuesto, interactivo.

#    The template for an interactive function definition is, as always:
   La plantilla para una definición de función interactiva es, como siempre:

#    ..src > elisp
#      (defun name-of-function (argument-list)
#        "documentation…"
#        (interactive-expression…)
#        body…)
#    < src..
   ..src > elisp
     (defun nombre-de-funcion (lista-de-argumentos)
       "documentacion…"
       (expresion-interactiva…)
       cuerpo…)
   < src..

#    What we need to do is fill in the slots.
   Lo que tenemos que hacer es llenar los espacios.

#    The name of the function should be self-explanatory and similar to the
#    existing @c{count-lines-region} name. This makes the name easier to
#    remember.  @c{count-words-region} is the obvious choice. Since that name
#    is now used for the standard Emacs command to count words, we will name
#    our implementation @c{count-words-example}.
   El nombre de la función debe ser auto-explicativo y similar al nombre ya
   existente @c{count-lines-region}. Esto hace que el nombre sea fácil de
   recordar. @c{count-words-region} es una buena elección. Ya que ese nombre
   ahora se usa para el comando estándar de Emacs para contar palabras,
   nombraremos a nuestra implementación @c{count-words-example}.

#    The function counts words within a region. This means that the argument
#    list must contain symbols that are bound to the two positions, the
#    beginning and end of the region. These two positions can be called
#    @'c{beginning} and @'c{end} respectively. The first line of the
#    documentation should be a single sentence, since that is all that is
#    printed as documentation by a command such as @c{apropos}. The
#    interactive expression will be of the form @'c{(interactive "r")}, since
#    that will cause Emacs to pass the beginning and end of the region to the
#    function's argument list. All this is routine.
   La función cuenta palabras dentro de una región. Esto significa que la lista
   de argumentos debe contener símbolos que esten ligados a las dos posiciones,
   el principio y fin de la región. Estas dos posiciones se pueden llamar
   @'c{inicio} y @'c{fin} respectivamente. La primer línea de la documentación
   deberia ser una solo frase, ya que esto es todo lo que imprimen comandos como
   @c{apropos}. La expresión interactiva tendra la forma @'c{(interactive "r")},
   puesto que esto provoca que Emacs pase el principio y fin de la región a la lista
   de argumentos de la función. Todo esto es rutina.

#    The body of the function needs to be written to do three tasks: first, to
#    set up conditions under which the @c{while} loop can count words, second,
#    to run the @c{while} loop, and third, to send a message to the user.
   El cuerpo de la función necesita ser escrito para hacer tres tareas:
   primero, configurar condiciones bajo las cuales el bucle @c{while} pueda
   contar palabras, segundo, ejecutar el bucle @c{while}, y tercero, enviar
   un mensaje al usuario.

#    When a user calls @c{count-words-example}, point may be at the beginning
#    or the end of the region. However, the counting process must start at the
#    beginning of the region. This means we will want to put point there if it
#    is not already there. Executing @c{(goto-char beginning)} ensures this.
#    Of course, we will want to return point to its expected position when the
#    function finishes its work. For this reason, the body must be enclosed in
#    a @c{save-excursion} expression.
   Cuando un usuario llama a @c{count-words-example}, el punto puede estar al
   principio o fin de la región. Sin embargo, el proceso de conteo debe empezar
   al principio de la región. Esto significa que querremos poner el punto hay si
   no lo esta. Ejecutando @c{(goto-char beginning)} aseguramos esto. Por
   supuesto, querremos devolver el punto a su posición esperada cuando la
   función termine su trabajo. Por esta razón, el cuerpo debe estar encerrado en
   una expresión @c{save-excursion}.

#    The central part of the body of the function consists of a @c{while} loop
#    in which one expression jumps point forward word by word, and another
#    expression counts those jumps. The true-or-false-test of the @c{while}
#    loop should test true so long as point should jump forward, and false when
#    point is at the end of the region.
   La parte central del cuerpo de la función consiste en un bucle @c{while}
   en el que una expresión salta el punto hacia adelante palabra por palabra,
   y otra expresión cuenta estos saltos. Si la prueba-verdadero-o-falso del
   bucle @c{while} es verdadera, el punto salta hacia adelante, y si es
   falsa el punto estaría al final de la región.

#    We could use @c{(forward-word 1)} as the expression for moving point
#    forward word by word, but it is easier to see what Emacs identifies as a
#    ‘word’ if we use a regular expression search.
   Podríamos usar @c{(forward-word 1)} como la expresión para mover
   el punto hacia adelante palabra por palabra, pero es mas fácil ver lo que
   Emacs identifica como una ‘palabra’ si usamos una búsqueda de expresión
   regular.

#    A regular expression search that finds the pattern for which it is
#    searching leaves point after the last character matched. This means that
#    a succession of successful word searches will move point forward word by
#    word.
   Una busqueda de expresión regular que encuentra el patron que esta buscando,
   deja el punto justo después del último carácter de la coincidencia. Esto
   significa que una sucesión de busquedas exitosas movera el punto hacia
   adelante palabra por palabra.

#    As a practical matter, we want the regular expression search to jump over
#    whitespace and punctuation between words as well as over the words
#    themselves. A regexp that refuses to jump over interword whitespace would
#    never jump more than one word!  This means that the regexp should include
#    the whitespace and punctuation that follows a word, if any, as well as the
#    word itself.  (A word may end a buffer and not have any following
#    whitespace or punctuation, so that part of the regexp must be optional.)
   Como cuestion práctica, queremos que la busqueda de expresiónes regulares
   salta a través de los espacios en blanco y tambien sobre la puntuacion entre
   palabras. Una regexp que no pueda saltar a través de espacios en blanco entre
   palabras ¡nunca saltara más de una palabra!. Esto significa que la regexp
   debe incluir el espacio en blanco y los signos de puntuación que siguen a una
   palabra, si la hay, asi como la palabra misma. (Una palabra puede terminar un
   búfer y no tener ninguna puntuacion o espacio en blanco, por lo que esa parte de
   la regexp debe ser opcional.)

#    Thus, what we want for the regexp is a pattern defining one or more word
#    constituent characters followed, optionally, by one or more characters
#    that are not word constituents. The regular expression for this is:
   Por lo tanto, queremos que el patron de la regexp defina uno o más caracteres
   constituyentes de la palabra, seguidos opcionalmente, por uno o más
   caracteres que no sean constituyentes de la palabra. La expresión regular
   para esto es:

#    ..example >
#      \w+\W*
#    < example..
   ..example >
     \w+\W*
   < example..

#    The buffer's syntax table determines which characters are and are not word
#    constituents. For more information about syntax, see Section
#    @l{elisp.html#Syntax Tables<>Syntax Tables} in @e{The GNU Emacs Lisp Reference Manual}.
   La tabla sintactica del búfer determina qué caracteres son o no
   constituyentes de palabras. Para más información sobre la sintaxis, Consulta la
   Sección @l{elisp.html#Syntax Tables<>Tablas de Sintaxis} en @e(El Manual de
   Referencia de GNU Emacs Lisp).

#    The search expression looks like this:
   La expresión se parece a esto:

#    ..src > elisp
#      (re-search-forward "\\w+\\W*")
#    < src..
   ..src > elisp
     (re-search-forward "\\w+\\W*")
   < src..

#    (Note that paired backslashes precede the @'c{w} and @'c{W}. A single
#    backslash has special meaning to the Emacs Lisp interpreter. It indicates
#    that the following character is interpreted differently than usual. For
#    example, the two characters, @'c{\n}, stand for @'{newline}, rather than
#    for a backslash followed by @'c{n}. Two backslashes in a row stand for an
#    ordinary, ‘unspecial’ backslash, so Emacs Lisp interpreter ends of seeing
#    a single backslash followed by a letter. So it discovers the letter is
#    special.)
   (Observa las barras invertidas que preceden a @'c{w} y @'c{W}. Una barra
   invertida tiene un significado especial para el intérprete Emacs Lisp. Indica
   que el siguiente caracter se interpreta de forma diferente a lo habitual. Por
   ejemplo, los dos caracteres, @'c{\n}, representan una @'{nueva línea}, en
   lugar de una barra invertida seguida por @'c{n}. Dos barras invertidas
   consecutivas representan una ‘barra invertida ordinaria’, así que el
   interprete de Emacs Lisp termina viendo una sola barra invertida seguida de
   una letra. Así descubre que la letra es especial.)

#    We need a counter to count how many words there are; this variable must
#    first be set to 0 and then incremented each time Emacs goes around the
#    @c{while} loop. The incrementing expression is simply:
   Necesitamon un contador para contar cuántas palabras hay; esta variable debe
   ponerse primero a 0 y luego incrementarse cada vez que Emacs recorra el bucle
   @c{while}. La expresión de incremento es simple:

#    ..src > elisp
#      (setq count (1+ count))
#    < src..
   ..src > elisp
     (setq cuenta (1+ cuenta))
   < src..

#    Finally, we want to tell the user how many words there are in the region.
#    The @c{message} function is intended for presenting this kind of
#    information to the user. The message has to be phrased so that it reads
#    properly regardless of how many words there are in the region: we don't
#    want to say that “there are 1 words in the region”. The conflict between
#    singular and plural is ungrammatical. We can solve this problem by using
#    a conditional expression that evaluates different messages depending on
#    the number of words in the region. There are three possibilities: no
#    words in the region, one word in the region, and more than one word. This
#    means that the @c{cond} special form is appropriate.
   Finalmente, necesitamos informar al usuario cuántas palabras hay en la
   región. La función @c{message} sirve para presentar este tipo de información al
   usuario. El mensaje tiene que estar redactado de manera que se lea
   correctamente independientemente de cuantas palabras haya en la región: no
   queremos decir que “hay 1 palabras en la región”. El conflicto entre
   singular y plural no es gramatical. Se puede resolver este problema usando
   una expresión condicional que evalue diferentes mensajes dependiendo del
   número de palabras en la región. Hay tres posibilidades: niguna palabra en la
   región, una palabra en la región, y más de una palabra. Esto significa que
   la forma especial @c{cond} es apropiada.

#    All this leads to the following function definition:
   Todo esto lleva a la siguiente definición de función:

#    ..src > elisp
   ..src > elisp
#      ;;; First version; has bugs!
     ;;; ¡Primer versión; tiene errores!
#      (defun count-words-example (beginning end)
     (defun count-words-example (inicio fin)
#        "Print number of words in the region.
#      Words are defined as at least one word-constituent
#      character followed by at least one character that
#      is not a word-constituent. The buffer's syntax
#      table determines which characters these are."
       "Imprime el número de palabras en la región.
     Las palabras se definen como al menos un caracter
     constituyente de palabras seguido por al menos un
     caracter no constituyente de palabras. La tabla de
     sintaxis del búfer determina qué caracteres son."
#        (interactive "r")
       (interactive "r")
#        (message "Counting words in region ... ")
       (message "Contando palaras en la región ... ")

#      ;;; 1. Set up appropriate conditions.
#        (save-excursion
#          (goto-char beginning)
#          (let ((count 0))
     ;;; 1. Establecer las condiciones apropiadas.
       (save-excursion
         (goto-char inicio)
         (let ((cuenta 0))

#      ;;; 2. Run the while loop.
#            (while (< (point) end)
#              (re-search-forward "\\w+\\W*")
#              (setq count (1+ count)))
     ;;; 2. Ejecutar el bucle while.
           (while (< (point) fin)
             (re-search-forward "\\w+\\W*")
             (setq cuenta (1+ cuenta)))

#      ;;; 3. Send a message to the user.
     ;;; 3. Enviar un mensaje al usuario.
#            (cond ((zerop count)
#                   (message
#                    "The region does NOT have any words."))
#                  ((= 1 count)
#                   (message
#                    "The region has 1 word."))
#                  (t
#                   (message
#                    "The region has %d words." count))))))
           (cond ((zerop cuenta)
                  (message
                   "La región NO tiene palabras."))
                 ((= 1 cuenta)
                  (message
                   "La región tiene 1 palabra."))
                 (t
                  (message
                   "La región tiene %d palabras." cuenta))))))
#    < src..
   < src..

#    As written, the function works, but not in all circumstances.
   Como esta escrito, la función funciona, pero no en todas las circunstancias.

# *** The Whitespace Bug in @c{count-words-example}
*** El error de espacio en blanco en @c{count-words-example}

#     The @c{count-words-example} command described in the preceding section
#     has two bugs, or rather, one bug with two manifestations. First, if you
#     mark a region containing only whitespace in the middle of some text, the
#     @c{count-words-example} command tells you that the region contains one
#     word!  Second, if you mark a region containing only whitespace at the end
#     of the buffer or the accessible portion of a narrowed buffer, the command
#     displays an error message that looks like this:
    El comando @c{count-words-example} descrito en la sección anterior tiene
    dos errores, o mas bien, un error con dos manifestaciones. Primero, si se
    marca una región que contiene solo espacios en blanco en el medio de algún
    texto el comando @c{count-words-example} dira que la región contiene una
    palabra. Segundo, si se marca una región conteniendo solo espacios en
    blanco al final del búfer o la porción accesible de un búfer reducido,
    el comando muestra un mensaje de error que tiene el siguiente aspecto:

#     ..example > elisp
#       Search failed: "\\w+\\W*"
#     < example..
    ..example > elisp
      Search failed: "\\w+\\W*"
    < example..

#     If you are reading this in Info in GNU Emacs, you can test for these bugs
#     yourself.
    Si estás leyendo esto en GNU Emacs, puedes probar estos errores por ti
    mismo.

#     First, evaluate the function in the usual manner to install it.
    Primero, evalúa la función de la manera habitual para instalarla.

#     If you wish, you can also install this keybinding by evaluating it:
    Si quieres, también puedes vincular la funcion al atajo @k(C-c =) evaluando
    lo siguiente:

#     ..src > elisp
#       (global-set-key "\C-c=" 'count-words-example)
#     < src..
    ..src > elisp
      (global-set-key "\C-c=" 'count-words-example)
    < src..

#     To conduct the first test, set mark and point to the beginning and end of
#     the following line and then type @k{C-c =} (or @k{M-x
#     count-words-example} if you have not bound @k{C-c =}):
    Para realizar la primer prueba, establece la marca y punto al principio y
    fin de la siguiente línea y luego presiona @k{C-c =} (o @k{M-x
    count-words-example} si no se vinculo a @k{C-c =}):

#     ..example >
#           one   two  three
#     < example..
    ..example >
          uno   dos  tres
    < example..

#     Emacs will tell you, correctly, that the region has three words.
    Emacs te dira, correctamente, que la región tiene tres palabras.

#     Repeat the test, but place mark at the beginning of the line and place
#     point just @e{before} the word @'{one}. Again type the command @k{C-c =}
#     (or @k{M-x count-words-example}). Emacs should tell you that the region
#     has no words, since it is composed only of the whitespace at the
#     beginning of the line. But instead Emacs tells you that the region has
#     one word!
    Repite la prueba, pero coloca la marca al principio de la línea y el punto
    justo @e{antes} de la palabra @'{uno}. De nuevo presiona @k{C-c =} (o @k{M-x
    count-words-example}). Emacs deberia decir que la región no tiene palabras,
    ya que está compuesta solo por espacios en blanco al inicio de la
    línea. ¡Pero en vez de eso, Emacs informa que la región tiene una palabra!

#     For the third test, copy the sample line to the end of the @f{*scratch*}
#     buffer and then type several spaces at the end of the line. Place mark
#     right after the word @'{three} and point at the end of line.  (The end of
#     the line will be the end of the buffer.)  Type @k{C-c =} (or @k{M-x
#     count-words-example}) as you did before. Again, Emacs should tell you
#     that the region has no words, since it is composed only of the whitespace
#     at the end of the line. Instead, Emacs displays an error message saying
#     @'{Search failed}.
    Para la tercer prueba, copia la línea de ejemplo al final del búfer
    @f{*scratch*} y luego escribe varios espacios al fin de la
    línea. Coloca la marca justo después de la palabra @'{tres} y
    el punto al fin de la línea. (El fin de la línea será el fin del búfer.)
    Como anteriormente, pulsa @k{C-c =} (o @k{M-x count-words-example}). De
    nuevo, Emacs deberia decir que la región no tiene palabras, ya que
    está compuesta solo por espacios en blanco al final de la línea. En
    su lugar, Emacs muestra un mensaje de error diciendo @'{Search failed}.

#     The two bugs stem from the same problem.
    Los dos errores provienen del mismo problema.

#     Consider the first manifestation of the bug, in which the command tells
#     you that the whitespace at the beginning of the line contains one word.
#     What happens is this: The @c{M-x count-words-example} command moves point
#     to the beginning of the region. The @c{while} tests whether the value of
#     point is smaller than the value of @c{end}, which it is. Consequently,
#     the regular expression search looks for and finds the first word. It
#     leaves point after the word.  @c{count} is set to one. The @c{while}
#     loop repeats; but this time the value of point is larger than the value
#     of @c{end}, the loop is exited; and the function displays a message
#     saying the number of words in the region is one. In brief, the regular
#     expression search looks for and finds the word even though it is outside
#     the marked region.
    Considera la primer manifestación del error, en la que el comando informa
    que el espacio en blanco al principio de la línea contiene una palabra. Lo
    que ocurre es lo siguiente: El comando @c{M-x count-words-example} mueve el
    punto al principio de la región. La prueba de @c{while} que verifica que el
    valor del punto sea más pequeño que el valor de @c{fin}, es verdadera. En
    consecuencia, la busqueda regexp busca y encuentra la primera palabra. Eso
    deja el punto después de la palabra. @c{count} se establece a uno. El bucle
    @c{while} se repite; pero esta vez el valor del punto es mayor al valor de
    @c{fin}, el bucle termina; y la función muestra un mensaje diciendo que el
    número de palabras en la región es uno. En resumen, la expresión regular
    busca y encuentra la palabra aunque esté fuera de la región marcada.

#     In the second manifestation of the bug, the region is whitespace at the
#     end of the buffer. Emacs says @'{Search failed}. What happens is that
#     the true-or-false-test in the @c{while} loop tests true, so the search
#     expression is executed. But since there are no more words in the buffer,
#     the search fails.
    En la segunda manifestación del error, la región es un espacio en blanco al
    final del búfer. Emacs dice @'{Search failed}. Lo que ocurre es que la
    prueba-verdadero-o-falso en el bucle @c{while} es verdadera, por lo que se
    ejecuta la expresión de búsqueda. Pero como no hay más palabras en el
    buffer, la búsqueda falla.

#     In both manifestations of the bug, the search extends or attempts to
#     extend outside of the region.
    En ambas manifestaciones del error, la búsqueda se extiende o intenta
    extenderse fuera de la región.

#     The solution is to limit the search to the region––this is a fairly
#     simple action, but as you may have come to expect, it is not quite as
#     simple as you might think.
    La solución es limitar la búsqueda a la región––esta es una acción bastante
    simple, pero como se puede esperar, no es tan simple como se podría
    pensar.

#     As we have seen, the @c{re-search-forward} function takes a search
#     pattern as its first argument. But in addition to this first, mandatory
#     argument, it accepts three optional arguments. The optional second
#     argument bounds the search. The optional third argument, if @c{t},
#     causes the function to return @c{nil} rather than signal an error if the
#     search fails. The optional fourth argument is a repeat count.  (In
#     Emacs, you can see a function's documentation by typing @k{C-h f}, the
#     name of the function, and then @k{RET}.)
    Como hemos visto, la función @c{re-search-forward} toma un patrón de
    búsqueda como su primer argumento. Pero además de este primer, argumento
    obligatorio, acepta tres argumentos opcionales. El segundo argumento
    opcional limita la búsqueda. El tercer argumento opcional, si es @c{t}, hace
    que la función devuelva @c{nil} en lugar de la señal de error si la búsqueda
    falla. El cuarto argumento opcional es un contador de repeticiones. (En
    Emacs, se puede ver la documentación de una la función pulsando @k{C-h f},
    seguido por el nombre de la función, y finalmente presionando @k{RET}.)

#     In the @c{count-words-example} definition, the value of the end of the
#     region is held by the variable @c{end} which is passed as an argument to
#     the function. Thus, we can add @c{end} as an argument to the regular
#     expression search expression:
    En la definición de @c{count-words-example}, el valor del fin de la región se
    almacena en la variable @c{fin} que se pasa como un argumento a la
    función. De este modo, podemos añadir @c{fin} como argumento en la
    búsqueda de la expresión regular:

#     ..src > elisp
#       (re-search-forward "\\w+\\W*" end)
#     < src..
    ..src > elisp
      (re-search-forward "\\w+\\W*" fin)
    < src..

#     However, if you make only this change to the @c{count-words-example}
#     definition and then test the new version of the definition on a stretch
#     of whitespace, you will receive an error message saying @'{Search
#     failed}.
    Sin embargo, con solo este cambio en la definición de
    @c{count-words-example} y luego de probar la nueva versión en una region de
    espacios en blanco, se recibirá un mensaje de error @'{Search failed}.

#     What happens is this: the search is limited to the region, and fails as
#     you expect because there are no word-constituent characters in the
#     region. Since it fails, we receive an error message. But we do not want
#     to receive an error message in this case; we want to receive the message
#     that "The region does NOT have any words."
    Lo que ocurre es esto: la búsqueda se limita a la región, y falla como se
    espera porque no hay caracteres constitutivos de palabras en la
    región. Puesto que falla, se recibe un mensaje de error. Pero no
    queremos recibir un mensaje de error en este caso; queremos recibir el
    mensaje de que "La región no tiene palabras".

#     The solution to this problem is to provide @c{re-search-forward} with a
#     third argument of @c{t}, which causes the function to return @c{nil}
#     rather than signal an error if the search fails.
    La solución a este problema es proveer un tercer argumento @c{t} a
    @c{re-search-forward}, haciendo que la función regrese @c{nil} en lugar
    de señalar un error si la búsqueda falla.

#     However, if you make this change and try it, you will see the message
#     “Counting words in region ... ” and … you will keep on seeing that
#     message …, until you type @k{C-g} @%c(keyboard-quit).
    Sin embargo, aun con este cambio, veremos el mensaje “Contando palaras en la
    región ... ” y … lo seguiremos viendo …, hasta presionar @k{C-g}
    @%c(keyboard-quit).

#     Here is what happens: the search is limited to the region, as before, and
#     it fails because there are no word-constituent characters in the region,
#     as expected. Consequently, the @c{re-search-forward} expression returns
#     @c{nil}. It does nothing else. In particular, it does not move point,
#     which it does as a side effect if it finds the search target. After the
#     @c{re-search-forward} expression returns @c{nil}, the next expression in
#     the @c{while} loop is evaluated. This expression increments the count.
#     Then the loop repeats. The true-or-false-test tests true because the
#     value of point is still less than the value of end, since the
#     @c{re-search-forward} expression did not move point. … and the cycle
#     repeats …
    Esto es lo que ocurre: la búsqueda se limitada a la región, como antes, y
    falla porque no hay caracteres constituyentes de palabras en la región, como
    se esperaba. Por consiguiente, la expresión @c{re-search-forward} devuelve
    @c{nil}. No hace nada más. En particular, no mueve el punto, cosa que hace
    como un efecto secundario si encuentra el objetivo de la búsqueda. Después
    de que la expresión @c{re-search-forward} devuelve @c{nil}, se evalua la
    siguiente expresión en el bucle @c{while}. Esta expresión incrementa el
    contador. Entonces el bucle se repite. La prueba-verdadero-o-falso es
    verdadera porque el valor del punto aun es menor al valor del final, ya que
    la expresión @c{re-search-forward} no movio el punto. … y el ciclo repite …

#     The @c{count-words-example} definition requires yet another modification,
#     to cause the true-or-false-test of the @c{while} loop to test false if
#     the search fails. Put another way, there are two conditions that must be
#     satisfied in the true-or-false-test before the word count variable is
#     incremented: point must still be within the region and the search
#     expression must have found a word to count.
    La definición de @c{count-words-example} requiere otra modificación para
    hacer que la prueba-verdadero-o-falso del bucle @c{while} sea falsa si la
    búsqueda falla. Dicho de otra manera, hay dos condiciones que deben
    cumplirse en la prueba-verdadero-o-falso antes de incrementar la variable de
    conteo: el punto debe estar dentro de la región y la expresión de búsqueda
    debe haber encontrado una palabra para contar.

#     Since both the first condition and the second condition must be true
#     together, the two expressions, the region test and the search expression,
#     can be joined with an @c{and} special form and embedded in the @c{while}
#     loop as the true-or-false-test, like this:
    Dado que ambas condiciones deben ser ciertas a la vez, la prueba de la
    región y la expresión de búsqueda, pueden unirse con una forma especial
    @c{and} e incrustarse en el bucle @c{while} como la prueba-verdadero-o-falso,
    asi:

#     ..src > elisp
#       (and (< (point) end) (re-search-forward "\\w+\\W*" end t))
#     < src..
    ..src > elisp
      (and (< (point) fin) (re-search-forward "\\w+\\W*" fin t))
    < src..

#     (For information about @c{and}, see Section @l{#The @c{kill-new} function}.)
    (Para obtener mas información sobre @c{and}, consulta la Seccion @l{#La función @c{kill-new}}.)

#     The @c{re-search-forward} expression returns @c{t} if the search succeeds
#     and as a side effect moves point. Consequently, as words are found,
#     point is moved through the region. When the search expression fails to
#     find another word, or when point reaches the end of the region, the
#     true-or-false-test tests false, the @c{while} loop exits, and the
#     @c{count-words-example} function displays one or other of its messages.
    La expresión @c{re-search-forward} devuelve @c{t} si la búsqueda tiene exito
    y, como efecto secundario, mueve el punto. En consecuencia, a medida que se
    encuentran las palabras, el punto se mueve a través de la región. Cuando la
    expresion de búsqueda no encuentra otra palabra, o cuando el punto llega al
    final de la región, la prueba-verdadero-o-falso da falso, termina el bucle
    @c{while}, y la función @c{count-words-example} muestra uno u otro de
    sus mensajes.

#     After incorporating these final changes, the @c{count-words-example}
#     works without bugs (or at least, without bugs that I have found!). Here
#     is what it looks like:
    Después de incorporar estos cambios finales, @c{count-words-example}
    funciona sin errores (¡o al menos, sin los errores que he
    encontrado!

#     ..src > elisp
    ..src > elisp
#       ;;; Final version: while
      ;;; Versión final: while
#       (defun count-words-example (beginning end)
      (defun count-words-example (inicio fin)
#         "Print number of words in the region."
        "Imprime número de palabras en la región."
#         (interactive "r")
#         (message "Counting words in region ... ")
        (interactive "r")
        (message "Contando palabras en la región ... ")

#       ;;; 1. Set up appropriate conditions.
      ;;; 1. Establecer las condiciones apropiadas.
#         (save-excursion
#           (let ((count 0))
#             (goto-char beginning)
        (save-excursion
          (let ((cuenta 0))
            (goto-char inicio)

#       ;;; 2. Run the while loop.
      ;;; 2. Ejecutar el bucle while
#             (while (and (< (point) end)
#                         (re-search-forward "\\w+\\W*" end t))
#               (setq count (1+ count)))
            (while (and (< (point) fin)
                        (re-search-forward "\\w+\\W*" fin t))
              (setq cuenta (1+ cuenta)))

#       ;;; 3. Send a message to the user.
      ;;; 3. Enviar un mensaje al usuario.
#             (cond ((zerop count)
#                    (message
            (cond ((zerop cuenta)
                   (message
#                     "The region does NOT have any words."))
                    "La región NO tiene palabras."))
#                   ((= 1 count)
#                    (message
                  ((= 1 cuenta)
                   (message
#                     "The region has 1 word."))
                    "La región tiene 1 palabra."))
#                   (t
#                    (message
                  (t
                   (message
#                     "The region has %d words." count))))))
                    "La región tiene %d palabras." cuenta))))))
#     < src..
    < src..

# ** Count Words Recursively
** Contar Palabras Recursivamente

#    You can write the function for counting words recursively as well as with
#    a @c{while} loop. Let's see how this is done.
   Puedes escribir la función para contar palabras tanto de manera
   recursiva como con un bucle @c{while}. Veamos cómo se hace esto.

#    First, we need to recognize that the @c{count-words-example} function has
#    three jobs: it sets up the appropriate conditions for counting to occur;
#    it counts the words in the region; and it sends a message to the user
#    telling how many words there are.
   En primer lugar, debemos reconocer que la función @c{count-words-example}
   tiene tres trabajos: establecer las condiciones apropiadas para que ocurra el
   conteo; contar las palabras en la región; y enviar un mensaje al usuario
   diciendo cuántas palabras hay.

#    If we write a single recursive function to do everything, we will receive
#    a message for every recursive call. If the region contains 13 words, we
#    will receive thirteen messages, one right after the other. We don't want
#    this!  Instead, we must write two functions to do the job, one of which
#    (the recursive function) will be used inside of the other. One function
#    will set up the conditions and display the message; the other will return
#    the word count.
   Si escribimos una sola función recursiva para hacer todo, recibiremos un
   mensaje por cada llamada recursiva. Si la región contiene 13 palabras,
   recibiremos trece mensajes, uno tras otro. ¡No queremos esto!. En su lugar,
   debemos escribir dos funciones para hacer el trabajo, una de las cuales (la función
   recursiva) se utilizara dentro de la otra. Una función configurará las
   condiciones y mostrara el mensaje; la otra devolverá el conteo de palabras.

#    Let us start with the function that causes the message to be displayed.
#    We can continue to call this @c{count-words-example}.
   Comencemos con la función que hace que se muestre el mensaje. Podemos
   continuar llamandola @c{count-words-example}.

#    This is the function that the user will call. It will be interactive.
#    Indeed, it will be similar to our previous versions of this function,
#    except that it will call @c{recursive-count-words} to determine how many
#    words are in the region.
   Esta es la función que el usuario llamara. Será interactiva. De hecho,
   será similar a nuestras versiones previas de esta función, excepto que
   llamará a @c{contar-palabras-recursivamente} para determinar cuántas palabras hay en
   la región.

#    We can readily construct a template for this function, based on our
#    previous versions:
   Podemos construir facilmente una plantilla para esta función, basada en
   versiones anteriores:

#    ..src > elisp
   ..src > elisp
#      ;; Recursive version; uses regular expression search
     ;; Versión Recursiva; usa búsqueda de expresiónes regulares
#      (defun count-words-example (beginning end)
     (defun count-words-example (inicio fin)
#        "documentation…"
       "documentacion…"
#        (interactive-expression…)
       (expresion-interactiva…)

#      ;;; 1. Set up appropriate conditions.
     ;;; 1. Establecer las condiciones apropiadas.
#        (explanatory message)
#        (set-up functions…
       (mensaje explicativo)
       (funciones de configuracion…

#      ;;; 2. Count the words.
     ;;; 2. Contar las palabras.
#          recursive call
         llamada recursiva

#      ;;; 3. Send a message to the user.
     ;;; 3. Envía un mensaje al usuario.
#          message providing word count))
         mensaje que proporciona el conteo de palabras))
#    < src..
   < src..

#    The definition looks straightforward, except that somehow the count
#    returned by the recursive call must be passed to the message displaying
#    the word count. A little thought suggests that this can be done by making
#    use of a @c{let} expression: we can bind a variable in the varlist of a
#    @c{let} expression to the number of words in the region, as returned by
#    the recursive call; and then the @c{cond} expression, using binding, can
#    display the value to the user.
   La definición parece sencilla, excepto que de alguna manera el conteo
   devuelto por la llamada recursiva debe ser pasado al mensaje que muestra el
   conteo de palabras. Un poco de reflexion sugiere que esto se puede hacer
   mediante una expresión @c{let}: podemos enlazar una variable en la lista de
   variables de la expresion @c{let} con el número de palabras de la región, tal y
   como lo devuelve la llamada recursiva; y entonces la expresión @c{cond}, podra
   mostrar el valor al usuario.

#    Often, one thinks of the binding within a @c{let} expression as somehow
#    secondary to the ‘primary’ work of a function. But in this case, what you
#    might consider the ‘primary’ job of the function, counting words, is done
#    within the @c{let} expression.
   Con frecuencia, uno piensa que el enlace dentro de una expresión @c{let} es
   algo secundario al trabajo ‘primario’ de una función. Pero en este caso,
   se podría considerar que el trabajo ‘primario’ de la función (contar
   palabras), ocurre dentro de la expresión @c{let}.

#    Using @c{let}, the function definition looks like this:
   Usando @c{let}, la definición de función se veria asi:

#    ..src > elisp
   ..src > elisp
#      (defun count-words-example (beginning end)
     (defun count-words-example (inicio fin)
#        "Print number of words in the region."
       "Imprime número de palabras en la región."
#        (interactive "r")
       (interactive "r")

#      ;;; 1. Set up appropriate conditions.
     ;;; 1. Establecer las condiciones apropiadas.
#        (message "Counting words in region ... ")
       (message "Contando palabras en la región ... ")
#        (save-excursion
       (save-excursion
#          (goto-char beginning)
           (goto-char inicio)

#      ;;; 2. Count the words.
     ;;; 2. Contar las palabras.
#          (let ((count (recursive-count-words end)))
         (let ((cuenta (contar-palabras-recursivamente fin)))

#      ;;; 3. Send a message to the user.
     ;;; 3. Enviar un mensaje al usuario.
#            (cond ((zerop count)
#                   (message
#                    "The region does NOT have any words."))
#                  ((= 1 count)
#                   (message
#                    "The region has 1 word."))
#                  (t
#                   (message
#                    "The region has %d words." count))))))
           (cond ((zerop cuenta)
                  (message
                   "La región NO tiene palabras."))
                 ((= 1 cuenta)
                  (message
                   "La región tiene 1 palabra."))
                 (t
                  (message
                   "La región tiene %d palabras." cuenta))))))
#    < src..
   < src..

#    Next, we need to write the recursive counting function.
   A continuacion, tenemos que escribir la función de conteo recursivo.

#    A recursive function has at least three parts: the ‘do-again-test’, the
#    ‘next-step-expression’, and the recursive call.
   Una función recursiva tiene al menos tres partes: la ‘prueba-hazlo-de-nuevo’, la
   ‘expresion-del-siguiente-paso’, y la llamada recursiva.

#    The do-again-test determines whether the function will or will not be
#    called again. Since we are counting words in a region and can use a
#    function that moves point forward for every word, the do-again-test can
#    check whether point is still within the region. The do-again-test should
#    find the value of point and determine whether point is before, at, or
#    after the value of the end of the region. We can use the @c{point}
#    function to locate point. Clearly, we must pass the value of the end of
#    the region to the recursive counting function as an argument.
   La prueba-hazlo-de-nuevo determina si la función será o no llamada de
   nuevo. Ya que estamos contando palabras en una región y podemos usar una
   función que mueve el punto hacia delante para cada palabra, la
   prueba-hazlo-de-nuevo puede evaluar si el punto todavía está dentro de la
   región. La prueba-hazlo-de-nuevo debe encontrar el valor del punto y
   determina si el punto está antes, en, o después del valor del final de la
   región. Podemos usar la función @c{point} para localizar el punto.
   Claramente, se debe pasar el valor del final de la región como un argumento a
   la función de conteo recursivo.

#    In addition, the do-again-test should also test whether the search finds a
#    word. If it does not, the function should not call itself again.
   Además, la prueba-hazlo-de-nuevo también tiene que probar si la búsqueda encuentra una
   palabra. Si no lo hace, la función no deberia llamarse de nuevo.

#    The next-step-expression changes a value so that when the recursive
#    function is supposed to stop calling itself, it stops. More precisely,
#    the next-step-expression changes a value so that at the right time, the
#    do-again-test stops the recursive function from calling itself again. In
#    this case, the next-step-expression can be the expression that moves point
#    forward, word by word.
   La expresion-del-siguiente-paso cambia un valor de modo que cuando se
   supone que la función recursiva deja de llamarse así misma, se detiene. Más
   precisamente, la expresion-del-siguiente-paso cambia un valor
   en el momento adecuado, la prueba-hazlo-de-nuevo detiene la función recursiva de
   llamarse a si misma otra vez. En este caso, la expresion-del-siguiente-paso
   puede ser la expresión que mueve el punto hacia adelante, palabra por
   palabra.

#    The third part of a recursive function is the recursive call.
   La tercera parte de una función recursiva es la llamada recursiva.

#    Somewhere, also, we also need a part that does the ‘work’ of the function,
#    a part that does the counting. A vital part!
   En algún lugar, también, necesitamos una parte que haga el ‘trabajo’ de la
   función, una parte que haga el conteo. ¡Una parte vital!

#    But already, we have an outline of the recursive counting function:
   Pero ya tenemos un esquema de la función de conteo recursivo:

#    ..src > elisp
#      (defun recursive-count-words (region-end)
#        "documentation…"
#        do-again-test
#        next-step-expression
#        recursive call)
#    < src..
   ..src > elisp
     (defun contar-palabras-recursivamente (fin-de-region)
       "documentacion…"
       prueba-hazlo-de-nuevo
       expresion-del-siguiente-paso
       llamada recursiva)
   < src..

#    Now we need to fill in the slots. Let's start with the simplest cases
#    first: if point is at or beyond the end of the region, there cannot be any
#    words in the region, so the function should return zero. Likewise, if the
#    search fails, there are no words to count, so the function should return
#    zero.
   Ahora tenemos que rellenar los huecos. Comencemos con los casos más simples:
   si el punto esta en o mas alla del fin de la región, no puede haber ninguna
   palabra en la región, así que la función deberia regresar cero. Del mismo
   modo, si la búsqueda falla no hay mas palabras para contar, por lo que la función
   tambien deberia regresar cero.

#    On the other hand, if point is within the region and the search succeeds,
#    the function should call itself again.
   Por otro lado, si el punto esta dentro de la región y la búsqueda tiene éxito, la
   función deberia volver a llamarse a si misma.

#    Thus, the do-again-test should look like this:
   Por lo tanto, la prueba-hazlo-de-nuevo se vería así:

#    ..src > elisp
#      (and (< (point) region-end)
#           (re-search-forward "\\w+\\W*" region-end t))
#    < src..
   ..src > elisp
     (and (< (point) fin-de-region)
          (re-search-forward "\\w+\\W*" fin-de-region t))
   < src..

#    Note that the search expression is part of the do-again-test––the function
#    returns @c{t} if its search succeeds and @c{nil} if it fails.  (See
#    Section @l{#The Whitespace Bug in @c{count-words-example}}, for an explanation
#    of how @c{re-search-forward} works.)
   Ten en cuenta que la expresión de búsqueda es parte de la prueba-hazlo-de-nuevo––la
   función devuelve @c{t} si su búsqueda tiene éxito y @c{nil} si
   falla. (Consulta la Seccion @l{#El error de espacio en blanco en @c{count-words-example}},
   para una explicación de cómo funciona @c{re-search-forward}.)

#    The do-again-test is the true-or-false test of an @c{if} clause. Clearly,
#    if the do-again-test succeeds, the then-part of the @c{if} clause should
#    call the function again; but if it fails, the else-part should return zero
#    since either point is outside the region or the search failed because
#    there were no words to find.
   La prueba-hazlo-de-nuevo es la prueba verdadero-o-falso de una cláusula
   @c{if}. Claramente si la prueba-hazlo-de-nuevo tiene éxito, la parte-then de la
   cláusula @c{if} llamaría a la función de nuevo; pero si falla, la parte-else
   deveria regresar cero ya que está fuera de la región o la búsqueda
   falló porque no había palabras que encontrar.

#    But before considering the recursive call, we need to consider the
#    next-step-expression. What is it?  Interestingly, it is the search part
#    of the do-again-test.
   Pero antes de considerar la llamada recursiva, se necesita considerar la
   expresion-del-siguiente-paso. ¿Qué es esto? Curiosamente, es la parte
   de la búsqueda de la prueba-hazlo-de-nuevo.

#    In addition to returning @c{t} or @c{nil} for the do-again-test,
#    @c{re-search-forward} moves point forward as a side effect of a successful
#    search. This is the action that changes the value of point so that the
#    recursive function stops calling itself when point completes its movement
#    through the region. Consequently, the @c{re-search-forward} expression is
#    the next-step-expression.
   Además de regresar @c{t} o @c{nil} en la prueba-hazlo-de-nuevo,
   @c{re-search-forward} mueve el punto hacia adelante como un efecto secundario
   de una búsqueda exitosa. Esta es la acción que cambia el valor de punto
   para que la función recursiva deje de llamarse a sí misma cuando el punto
   complete su movimiento a través de la región. Por consiguiente, la
   expresión @c{re-search-forward} es la expresion-del-siguiente-paso.

#    In outline, then, the body of the @c{recursive-count-words} function looks
#    like this:
   Entonces, en la plantilla, el cuerpo de la función @c{contar-palabras-recursivamente} se
   ve asi:

#    ..src > elisp
#      (if do-again-test-and-next-step-combined
#          ;; then
#          recursive-call-returning-count
#        ;; else
#        return-zero)
#    < src..
   ..src > elisp
     (if prueba-hazlo-de-nuevo-y-del-siguiente-paso-combinadas
         ;; then
         llamada-recursiva-regresando-la-cuenta
       ;; else
       regresar-cero)
   < src..

#    How to incorporate the mechanism that counts?
   ¿Cómo incorporar el mecanismo que cuenta?

#    If you are not used to writing recursive functions, a question like this
#    can be troublesome. But it can and should be approached systematically.
   Si no estás acostumbrado a escribir funciones recursivas, una pregunta
   como esta puede ser un problema. Pero puede y debe abordarse
   sistemáticamente.

#    We know that the counting mechanism should be associated in some way with
#    the recursive call. Indeed, since the next-step-expression moves point
#    forward by one word, and since a recursive call is made for each word, the
#    counting mechanism must be an expression that adds one to the value
#    returned by a call to @c{recursive-count-words}.
   Sabemos que el mecanismo de conteo debe estar asociado de algúna manera con
   la llamada recursiva. De hecho, dado que la expresion-del-siguiente-paso
   mueve el punto hacia adelante en una palabra, y dado que se hace una llamada
   recursiva para cada palabra, el mecanismo de conteo debe ser una expresión
   que agregue uno al valor devuelto en una llamada a @c{contar-palabras-recursivamente}

#    Consider several cases:
   Considera varios casos:

#    - If there are two words in the region, the function should return a value
#      resulting from adding one to the value returned when it counts the first
#      word, plus the number returned when it counts the remaining words in the
#      region, which in this case is one.
   - Si hay dos palabras en la región, la función debe devolver un valor
     resultante de sumar uno al valor devuelto al contar la primera palabra, más
     el número devuelto al contar las palabras restantes en la región, que en
     este caso es uno.

#    - If there is one word in the region, the function should return a value
#      resulting from adding one to the value returned when it counts that
#      word, plus the number returned when it counts the remaining words in the
#      region, which in this case is zero.
   - Si hay una palabra en la región, la función devolvería un valor
     que resulte de sumar uno al valor devuelto cuando cuenta esa
     palabra, más el número devuelto cuando cuenta las palabras restantes
     en la región, que en este caso es cero.

#    - If there are no words in the region, the function should return zero.
   - Si no hay palabras en la región, la función deberia regresar cero.


#    From the sketch we can see that the else-part of the @c{if} returns zero
#    for the case of no words. This means that the then-part of the @c{if}
#    must return a value resulting from adding one to the value returned from a
#    count of the remaining words.
   En el esquema podemos ver que la parte-else del @c{if} devuelve cero
   para el caso en el que no hay palabras. Esto significa que la parte-then
   del @c{if} debe devolver un valor resultante de sumar uno al valor
   devuelto por el conteo las palabras restantes.

#    The expression will look like this, where @c{1+} is a function that adds
#    one to its argument.
   La expresión se vera asi, donde @c{1+} es una función que añade uno a
   su argumento.

#    ..src > elisp
#      (1+ (recursive-count-words region-end))
#    < src..
   ..src > elisp
     (1+ (contar-palabras-recursivamente fin-de-region))
   < src..

#    The whole @c{recursive-count-words} function will then look like this:
   La función @c(contar-palabras-recursivamente) completa se vera asi:

#    ..src > elisp
   ..src > elisp
#      (defun recursive-count-words (region-end)
#        "documentation…"
     (defun contar-palabras-recursivamente (fin-de-region)
       "documentacion…"

#      ;;; 1. do-again-test
     ;;; 1. prueba-hazlo-de-nuevo
#        (if (and (< (point) region-end)
#                 (re-search-forward "\\w+\\W*" region-end t))
       (if (and (< (point) fin-de-region)
                (re-search-forward "\\w+\\W*" fin-de-region t))

#      ;;; 2. then-part: the recursive call
     ;;; 2. parte-then: la llamada recursiva
#            (1+ (recursive-count-words region-end))
           (1+ (contar-palabras-recursivamente fin-de-region))

#      ;;; 3. else-part
#          0))
     ;;; 3. parte-else
         0))
#    < src..
   < src..

#    Let's examine how this works:
   Examinemos como funciona esto:

#    If there are no words in the region, the else part of the @c{if}
#    expression is evaluated and consequently the function returns zero.
   Si no hay palabras en la región, la parte-else de la expresión @c{if} es
   evaluada y, por tanto, la función devuelve cero.

#    If there is one word in the region, the value of point is less than the
#    value of @c{region-end} and the search succeeds. In this case, the
#    true-or-false-test of the @c{if} expression tests true, and the then-part
#    of the @c{if} expression is evaluated. The counting expression is
#    evaluated. This expression returns a value (which will be the value
#    returned by the whole function) that is the sum of one added to the value
#    returned by a recursive call.
   Si hay una palabra en la región, el valor del punto es menor que el valor
   de @c{fin-de-region} y la búsqueda tiene éxito. En este caso, la
   prueba-verdadero-o-falso de la expresión @c{if} es verdadera, y se evalua
   la parte-then de la expresión @c{if}. Se evalua la expresión de conteo.
   Esta expresión devuelve un valor (que será el valor devuelto por
   toda la función) que es la suma de uno añadida al valor devuelto por
   una llamada recursiva.

#    Meanwhile, the next-step-expression has caused point to jump over the
#    first (and in this case only) word in the region. This means that when
#    @c{(recursive-count-words region-end)} is evaluated a second time, as a
#    result of the recursive call, the value of point will be equal to or
#    greater than the value of region end. So this time,
#    @c{recursive-count-words} will return zero. The zero will be added to
#    one, and the original evaluation of @c{recursive-count-words} will return
#    one plus zero, which is one, which is the correct amount.
   Mientras tanto, la expresion-del-siguiente-paso ha hecho que punto salte
   sobre la primera (y en este caso única) palabra en la región. Esto significa
   que cuando @c{(contar-palabras-recursivamente fin-de-region)} se evalua una
   segunda vez, como resultado de la llamada recursiva, el valor del punto será
   igual o mayor que el valor del fin de región. Así que esta vez,
   @c{contar-palabras-recursivamente} devolverá cero. El cero se sumara a uno, y
   la evaluación original de @c{contar-palabras-recursivamente} devolverá uno
   más cero, que es uno y es la cantidad correcta.

#    Clearly, if there are two words in the region, the first call to
#    @c{recursive-count-words} returns one added to the value returned by
#    calling @c{recursive-count-words} on a region containing the remaining
#    word––that is, it adds one to one, producing two, which is the correct
#    amount.
   Claramente, si hay dos palabras en la región, la primer llamada a
   @c{contar-palabras-recursivamente} devuelve uno mas el valor devuelto por
   @c{contar-palabras-recursivamente} en una región que contiene la palabra
   restante––es decir, suma uno a uno, produciendo dos, que es la
   cantidad correcta.

#    Similarly, if there are three words in the region, the first call to
#    @c{recursive-count-words} returns one added to the value returned by
#    calling @c{recursive-count-words} on a region containing the remaining two
#    words––and so on and so on.
   De manera similar, si hay tres palabras en la región, la primer llamada
   @c{contar-palabras-recursivamente} devuelve uno mas el valor devuelto de
   @c{contar-palabras-recursivamente} en una región que contiene las dos
   palabras restantes––y así sucesivamente.

#    With full documentation the two functions look like this:
   Con la documentación completa las dos funciones serian asi:

#    The recursive function:
   La función recursiva:

#    ..src > elisp
   ..src > elisp
#      (defun recursive-count-words (region-end)
     (defun contar-palabras-recursivamente (fin-de-region)
#        "Number of words between point and REGION-END."
       "Número de palabras entre punto y FIN-DE-REGION."

#      ;;; 1. do-again-test
     ;;; 1. prueba-hazlo-de-nuevo
#        (if (and (< (point) region-end)
#                 (re-search-forward "\\w+\\W*" region-end t))
       (if (and (< (point) fin-de-region)
                (re-search-forward "\\w+\\W*" fin-de-region t))

#      ;;; 2. then-part: the recursive call
     ;;; 2. parte-then: la llamada recursiva
#            (1+ (recursive-count-words region-end))
           (1+ (contar-palabras-recursivamente fin-de-region))

#      ;;; 3. else-part
     ;;; 3. parte-else
#          0))
         0))
#    < src..
   < src..

#    The wrapper:
   El envoltorio:

#    ..src > elisp
   ..src > elisp
#      ;;; Recursive version
     ;;; Versión Recursiva
#      (defun count-words-example (beginning end)
     (defun count-words-example (inicio fin)
#        "Print number of words in the region.
       "Imprime número de palabras en la región.

#      Words are defined as at least one word-constituent
#      character followed by at least one character that is
#      not a word-constituent. The buffer's syntax table
#      determines which characters these are."
     Las palabras se definen como al menos un caracter
     constituyente de palabras seguido por al menos un
     caracter no constituyente de palabras. La tabla de
     sintaxis del búfer determina qué caracteres son."
#        (interactive "r")
       (interactive "r")
#        (message "Counting words in region ... ")
       (message "Contando palabras en la región ... ")
#        (save-excursion
#          (goto-char beginning)
       (save-excursion
           (goto-char inicio)
#          (let ((count (recursive-count-words end)))
         (let ((cuenta (contar-palabras-recursivamente fin)))
#            (cond ((zerop count)
           (cond ((zerop cuenta)
#                   (message
                  (message
#                    "The region does NOT have any words."))
                   "La región NO tiene palabras."))
#                  ((= 1 count)
                 ((= 1 cuenta)
#                   (message "The region has 1 word."))
                  (message "La región tiene 1 palabra."))
#                  (t
#                   (message
#                    "The region has %d words." count))))))
                 (t
                  (message
                   "La región tiene %d palabras." cuenta))))))
#    < src..
   < src..

# ** Exercise: Counting Punctuation
** Ejercicio: Conteo de signos de puntuación

#    Using a @c{while} loop, write a function to count the number of
#    punctuation marks in a region––period, comma, semicolon, colon,
#    exclamation mark, and question mark. Do the same using recursion.
   Usando un bucle @c{while}, escribe una función para contar el número de
   signos de puntuación en una región––punto, coma, punto y coma, dos
   puntos, signos de interrogacion y exclamación. Has lo mismo usando
   recursión.

# * Counting Words in a @c{defun}
* Contando palabras en una @c{defun}

#   Our next project is to count the number of words in a function definition.
#   Clearly, this can be done using some variant of @c{count-words-example}. See
#   Section @l{#Counting: Repetition and Regexps}. If we are just going to
#   count the words in one definition, it is easy enough to mark the definition
#   with the @k{C-M-h} @%c(mark-defun) command, and then call
#   @c{count-words-example}.
  Nuestro siguiente proyecto es contar el número de palabras en una definición
  de función. Claramente, esto se puede hacer usando alguna variante de
  @c{count-words-example}. Consulta la Seccion @l{#Conteo: repetición y regexps}.
  Si solo vamos a contar las palabras en una definición, es bastante fácil
  marcar la definición con el comando @k{C-M-h} @%c(mark-defun), y luego llamar
  a @c{count-words-example}.

#   However, I am more ambitious: I want to count the words and symbols in
#   every definition in the Emacs sources and then print a graph that shows how
#   many functions there are of each length: how many contain 40 to 49 words or
#   symbols, how many contain 50 to 59 words or symbols, and so on. I have
#   often been curious how long a typical function is, and this will tell.
  Sin embargo, soy más ambicioso: quiero contar las palabras y símbolos en
  todas las definiciónes del codigo de Emacs y despues imprimir un grafico que
  muestre cuántas funciones hay de cada tamaño: cuántas contienen de 40 a 49
  palabras o símbolos, cuántas contienen de 50 a 59 palabras o símbolos, y
  así sucesivamente. A menudo he tenido curiosidad por saber cuanto abarca una
  función típica, y esto lo dira.

#   Described in one phrase, the histogram project is daunting; but divided
#   into numerous small steps, each of which we can take one at a time, the
#   project becomes less fearsome. Let us consider what the steps must be:
  Descrito en una frase, el proyecto del histograma es desalentador; pero dividido
  en muchos pequeños pasos, dando uno a uno a la vez, el proyecto se vuelve
  menos atemorizante. Consideremos cuales deberian ser los pasos a seguir:

#   - First, write a function to count the words in one definition. This
#     includes the problem of handling symbols as well as words.
  - Primero, escribir una función para contar las palabras en una
    definición. Esto incluye el problema de manejar tanto símbolos como
    palabras.

#   - Second, write a function to list the numbers of words in each function in
#     a file. This function can use the @c{count-words-in-defun} function.
  - Segundo, escribir una función para listar el número de palabras de cada
    función en un fichero. Esta función puede usar la función
    @c{count-words-in-defun}.

#   - Third, write a function to list the numbers of words in each function in
#     each of several files. This entails automatically finding the various
#     files, switching to them, and counting the words in the definitions
#     within them.
  - Tercero, escribir una función para listar el número de palabras en cada
    función en cada uno de los ficheros. Esto implica encontrar automáticamente
    los diferentes ficheros, cambiar entre ellos, y contar las palabras en las
    definiciones dentro de cada uno.

#   - Fourth, write a function to convert the list of numbers that we created
#     in step three to a form that will be suitable for printing as a graph.
  - Cuarto, escribir una función para convertir la lista de números que
    creamos en el paso tres a un formulario que sea adecuado para
    imprimir en forma de grafico.

#   - Fifth, write a function to print the results as a graph.
  - Quinto, escribir una función para imprimir los resultados como un grafico.


#   This is quite a project!  But if we take each step slowly, it will not be
#   difficult.
  ¡Este es un gran proyecto! Pero si tomamos cada paso lentamente, no será
  difícil.

# ** What to Count?
** ¿Qué contar?

#    When we first start thinking about how to count the words in a function
#    definition, the first question is (or ought to be) what are we going to
#    count?  When we speak of ‘words’ with respect to a Lisp function
#    definition, we are actually speaking, in large part, of ‘symbols’. For
#    example, the following @c{multiply-by-seven} function contains the five
#    symbols @c{defun}, @c{multiply-by-seven}, @c{number}, @c{*}, and @c{7}.
#    In addition, in the documentation string, it contains the four words
#    @'{Multiply}, @'{NUMBER}, @'{by}, and @'{seven}. The symbol @'{number} is
#    repeated, so the definition contains a total of ten words and symbols.
   Cuando empezamos a pensar en como contar las palabras
   en una definición de función, la primera pregunta es (o deberia ser) ¿qué
   vamos a contar?  Cuando hablamos de ‘palabras’ con repecto a una
   definición de función Lisp, en realidad estamos hablando, en gran parte, de
   ‘símbolos’. Por ejemplo, la siguiente función @c{multiplicar-por-siete}
   contiene los cinco símbolos @c{defun}, @c{multiplicar-por-siete}, @c{numero},
   @c{*}, y @c{7}. Además, en la cadena de documentación, contiene cuatro
   palabras @'{Multiplicar}, @'{NUMERO}, @'{por}, y @'{siete}. El símbolo
   @'{número} se repite, por lo que la definición contiene un total de diez
   palabras y símbolos.

#    ..src > elisp
#      (defun multiply-by-seven (number)
#        "Multiply NUMBER by seven."
#        (* 7 number))
#    < src..
   ..src > elisp
     (defun multiplicar-por-siete (numero)
       "Multiplica NUMERO por siete."
       (* 7 numero))
   < src..

#    However, if we mark the @c{multiply-by-seven} definition with @k{C-M-h}
#    @%c{mark-defun}, and then call @c{count-words-example} on it, we will find
#    that @c{count-words-example} claims the definition has eleven words, not ten!
#    Something is wrong!
   Sin embargo, si marcamos la definición @c{multiplicar-por-siete} con @k{C-M-h}
   @%c{mark-defun}, y luego llamamos a @c{count-words-example} en ella,
   encontraremos que @c{count-words-example} afirma que la definición tiene once
   palabras, no diez ¡Alguna cosa está mal!

#    The problem is twofold: @c{count-words-example} does not count the @'{*} as a
#    word, and it counts the single symbol, @c{multiply-by-seven}, as
#    containing three words. The hyphens are treated as if they were interword
#    spaces rather than intraword connectors: @'{multiply-by-seven} is counted
#    as if it were written @'{multiply by seven}.
   El problema es doble: @c{count-words-example} no cuenta el @'{*} como una
   palabra, y cuenta el símbolo unico, @c{multiplicar-por-siete},
   conteniendo tres palabras. Los guines se tratan como si fueran
   espacios entre palabras en lugar de conectores entre palabras
   @'{multiplicar-por-siete} se cuenta como si fuese escrito
   @'{multiplicar por siete}.

#    The cause of this confusion is the regular expression search within the
#    @c{count-words-example} definition that moves point forward word by word. In
#    the canonical version of @c{count-words-example}, the regexp is:
   La causa de esta confusión es la expresión regular que busca la definición
   @c{count-words-example} que mueve el punto hacia adelante palabra por
   palabra. En la versión canónica de @c{count-words-example}, la regexp es:

#    ..example >
#      "\\w+\\W*"
#    < example..
   ..example >
     "\\w+\\W*"
   < example..

#    This regular expression is a pattern defining one or more word constituent
#    characters possibly followed by one or more characters that are not word
#    constituents. What is meant by ‘word constituent characters’ brings us to
#    the issue of syntax, which is worth a section of its own.
   Esta expresión regular es un patrón que define uno o más caracteres
   constituyentes de palabras, posiblemente seguidos por uno o más caracteres
   que no son constituyentes de palabras. Lo que se entiende por ‘caracteres
   constituyentes de palabras’ nos lleva a la cuestión de la sintaxis, que merece
   una sección en por sí misma.

# ** What Constitutes a Word or Symbol?
** ¿Qué constituye una palabra o símbolo?

#    Emacs treats different characters as belonging to different @:{syntax
#    categories}. For example, the regular expression, @'{\\w+}, is a pattern
#    specifying one or more @e{word constituent} characters. Word constituent
#    characters are members of one syntax category. Other syntax categories
#    include the class of punctuation characters, such as the period and the
#    comma, and the class of whitespace characters, such as the blank space and
#    the tab character.  (For more information, see Section
#    @l{elisp.html#Syntax Tables<>Syntax Tables} in @e{The GNU Emacs Lisp
#    Reference Manual}.)
   Emacs trata diferentes caracteres como pertenecientes a diferentes
   @:{categorías sintacticas}. Por ejemplo, la expresión regular, @'{\\w+}, es
   un patrón que especifica uno o más caracteres @e{constituyentes de
   palabras}. Los caracteres constituyentes de palabras son miembros de una
   categoría sintactica. Otras categoría sintactica incluye la clase de
   caracteres de puntuación, como el punto y la coma, y la clase de caracteres
   de espacio en blanco, como el espacio en blanco o el tabulador. (Para más
   información, consulta la Seccion @l{elisp.html#Syntax Tables<>Tablas de Sintaxis} en @e(El
   Manual de Referencia GNU Emacs Lisp).)

#    Syntax tables specify which characters belong to which categories.
#    Usually, a hyphen is not specified as a ‘word constituent character’.
#    Instead, it is specified as being in the ‘class of characters that are
#    part of symbol names but not words.’  This means that the
#    @c{count-words-example} function treats it in the same way it treats an
#    interword white space, which is why @c{count-words-example} counts
#    @'{multiply-by-seven} as three words.
   Las tablas sintacticas especifican qué caracteres pertenecen a qué
   categorías. Normalmente un guión no está especificado como un ‘caracter
   constiyente de una palabra’. En su lugar, se especifica como perteneciente a
   la ‘clase de caracteres que son parte de los nombres de símbolos, pero no de
   las palabras’.  Esto significa que la función @c{count-words-example} la
   trata del mismo modo que trata un espacio en blanco entre palabras, por lo
   qué la funcion @c{count-words-example} cuenta a @'{multiplicar-por-siete} como
   tres palabras.

#    There are two ways to cause Emacs to count @'{multiply-by-seven} as one
#    symbol: modify the syntax table or modify the regular expression.
   Hay dos maneras de hacer que Emacs cuente @'{multiplicar-por-siete} como un
   símbolo: modificar la tabla sintactica o modificar la expresión regular.

#    We could redefine a hyphen as a word constituent character by modifying
#    the syntax table that Emacs keeps for each mode. This action would serve
#    our purpose, except that a hyphen is merely the most common character
#    within symbols that is not typically a word constituent character; there
#    are others, too.
   Se podría redefinir un guión como un caracter constituyente
   de una palabra modificando la tabla de sintaxis que Emacs guarda para cada
   modo. Esta acción serviría a nuestro propósito, excepto que un guion es
   simplemente el caracter más común dentro de los símbolos que no es son tipicamente un
   caracter constituyente de una palabra; hay otros, también.

#    Alternatively, we can redefine the regexp used in the @c{count-words-example}
#    definition so as to include symbols. This procedure has the merit of
#    clarity, but the task is a little tricky.
   Alternativamente, podemos redefinir la regexp usada en la definición
   de @c{count-words-example} para incluir símbolos. Este procedimiento tiene el mérito
   de la claridad, pero la tarea es un poco dificil.

#    The first part is simple enough: the pattern must match “at least one
#    character that is a word or symbol constituent”. Thus:
   La primera parte es bastante simple: el patrón debe coincidir con “al
   menos un carácter que sea una palabra o un símbolo constituyente”. Asi:

#    ..example >
#      "\\(\\w\\|\\s_\\)+"
#    < example..
   ..example >
     "\\(\\w\\|\\s_\\)+"
   < example..

#    The @'c{\\(} is the first part of the grouping construct that includes the
#    @'c{\\w} and the @'c{\\s_} as alternatives, separated by the @'c{\\|}. The
#    @'c{\\w} matches any word-constituent character and the @'c{\\s_} matches
#    any character that is part of a symbol name but not a word-constituent
#    character. The @'c{+} following the group indicates that the word or
#    symbol constituent characters must be matched at least once.
   El @'c{\\(} es la primera parte del constructor de agrupacion que incluye el
   @'c{\\w} y el @'c{\\s_} como alternativas, separadas por @'c{\\|}. El @'c{\\w}
   coincide con cualquier caracter constituyente de una palabras y @'c{\\s_} con
   cualquier caracter que forme parte de un símbolo no constituyente de
   palabras. El signo @'c{+} a continuacion de la agrupacion indica que los caracteres que
   componen la palabra o el símbolo deben coincidir al menos una vez.

#    However, the second part of the regexp is more difficult to design. What
#    we want is to follow the first part with “optionally one or more
#    characters that are not constituents of a word or symbol”. At first, I
#    thought I could define this with the following:
   Sin embargo, la segunda parte de la regexp es más difícil de diseñar. Lo que
   queremos es seguir la primera parte con “opcionalmente uno o más
   caracteres que no constituyen una palabra o símbolo”. Al principio, pense
   que esto se podría definir con lo siguiente:

#    ..example >
#      "\\(\\W\\|\\S_\\)*"
#    < example..
   ..example >
     "\\(\\W\\|\\S_\\)*"
   < example..

#    The upper case @'c{W} and @'c{S} match characters that are @e{not} word or
#    symbol constituents. Unfortunately, this expression matches any character
#    that is either not a word constituent or not a symbol constituent. This
#    matches any character!
   Las mayúsculas @'c{W} y @'c{S} coinciden con caracteres que @e{no} son
   parte de palabras o símbolos. Desafortunadamente, esta expresión
   coincide con cualquier caracter que no sea parte de una palabra o simbolo.
   ¡Esto coincide con cualquier caracter!

#    I then noticed that every word or symbol in my test region was followed by
#    white space (blank space, tab, or newline). So I tried placing a pattern
#    to match one or more blank spaces after the pattern for one or more word
#    or symbol constituents. This failed, too. Words and symbols are often
#    separated by whitespace, but in actual code parentheses may follow symbols
#    and punctuation may follow words. So finally, I designed a pattern in
#    which the word or symbol constituents are followed optionally by
#    characters that are not white space and then followed optionally by white
#    space.
   Entonces note que cada palabra o símbolo en mi región de prueba iba
   seguido de un espacio en blanco (espacio en blanco, tabulador, o línea
   nueva). Así que intente colocar un patrón para que coincidiese con uno o más espacios
   en blanco después del patrón para una o más palabras o símbolos
   constituyentes. Esto tambien falló. Las palabras y los símbolos suelen
   estar separados por espacios en blanco, pero en el código real los
   paréntesis pueden ir despues de los símbolos y la puntuación puede seguir a las
   palabras. Así que finalmente, diseñe un patrón en el que los componentes de
   la palabra o simbolo van seguidos opcionalmente por caracteres que no son
   espacios en blanco, seguidos a su vez por espacios en blanco opcionales.

#    Here is the full regular expression:
   Aquí está la expresión regular completa:

#    ..example >
#      "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*"
#    < example..
   ..example >
     "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*"
   < example..

# ** The @c{count-words-in-defun} Function
** La función @c{contar-palabras-en-definicion}

#    We have seen that there are several ways to write a @c{count-words-region}
#    function. To write a @c{count-words-in-defun}, we need merely adapt one
#    of these versions.
   Hemos visto que hay varias maneras de escribir la función
   @c{count-word-region}. Para escribir @c{contar-palabras-en-definicion},
   basta con adaptar una de estas versiones.

#    The version that uses a @c{while} loop is easy to understand, so I am
#    going to adapt that. Because @c{count-words-in-defun} will be part of a
#    more complex program, it need not be interactive and it need not display a
#    message but just return the count. These considerations simplify the
#    definition a little.
   La versión que utiliza un bucle @c{while} es fácil de comprender, así que voy
   a adaptarla. Debido a que @c{contar-palabras-en-definicion} formara parte de
   un programa más complejo, no necesita ser interactivo y ni mostrar un
   mensaje, solamente devolver el conteo. Estas consideraciones simplifican un
   poco la definición.

#    On the other hand, @c{count-words-in-defun} will be used within a buffer
#    that contains function definitions. Consequently, it is reasonable to ask
#    that the function determine whether it is called when point is within a
#    function definition, and if it is, to return the count for that
#    definition. This adds complexity to the definition, but saves us from
#    needing to pass arguments to the function.
   Por otro lado, @c{contar-palabras-en-definicion} se utilizara dentro de un
   buffer que contiene definiciones de función. Por consiguiente, es razonable
   pedir que la función determine si se llama cuando el punto está dentro de una
   definición de función, y si lo esta, que devuelva el conteo para esa
   definición. Esto añade complejidad a la definición, pero nos ahorra la
   necesidad de pasar argumentos a la función.

#    These considerations lead us to prepare the following template:
   Estas consideraciones nos llevan a preparar la siguiente plantilla:

#    ..src > elisp
#      (defun count-words-in-defun ()
#        "documentation…"
#        (set up…
#           (while loop…)
#         return count)
#    < src..
   ..src > elisp
     (defun contar-palabras-en-definicion ()
       "documentacion…"
       (configuracion…
          (bucle while…)
        regresar conteo)
   < src..

#    As usual, our job is to fill in the slots.
   Como de costumbre, nuestro trabajo es rellenar los huecos.

#    First, the set up.
   Primero, la configuración.

#    We are presuming that this function will be called within a buffer
#    containing function definitions. Point will either be within a function
#    definition or not. For @c{count-words-in-defun} to work, point must move
#    to the beginning of the definition, a counter must start at zero, and the
#    counting loop must stop when point reaches the end of the definition.
   Suponemos que esta función se llamara dentro de un búfer que contiene
   definiciones de función. El punto estara o no dentro de una definición de
   función. Para que @c{contar-palabras-en-definicion} funcione, el punto
   debe moverse al principio de la definición, un contador debe empezar en cero,
   y el bucle de conteo debe parar cuando el punto alcance el final de la definición.

#    The @c{beginning-of-defun} function searches backwards for an opening
#    delimiter such as a @'{(} at the beginning of a line, and moves point to
#    that position, or else to the limit of the search. In practice, this
#    means that @c{beginning-of-defun} moves point to the beginning of an
#    enclosing or preceding function definition, or else to the beginning of
#    the buffer. We can use @c{beginning-of-defun} to place point where we
#    wish to start.
   La función @c{beginning-of-defun} busca hacia atrás un delimitador de
   apertura como @'{(} al principio de una línea, y mueve el punto a esa
   posición, o sino al límite de la búsqueda. En la práctica, esto significa
   que @c{beginning-of-defun} mueve el punto al principio de la funcion que lo
   rodea o a la anterior función, o bien al principio del buffer.

#    The @c{while} loop requires a counter to keep track of the words or
#    symbols being counted. A @c{let} expression can be used to create a local
#    variable for this purpose, and bind it to an initial value of zero.
   El bucle @c{while} requiere un contador para registrar las palabras o
   símbolos que se estan contando. Una expresión @c{let} puede ser usada para
   crear una variable local para este propósito, y vincularse a un valor inicial
   de cero.

#    The @c{end-of-defun} function works like @c{beginning-of-defun} except
#    that it moves point to the end of the definition.  @c{end-of-defun} can be
#    used as part of an expression that determines the position of the end of
#    the definition.
   La función @c{end-of-defun} opera como @c{beginning-of-defun} excepto
   que mueve el punto al fin de la definición. @c{end-of-defun} puede usarse
   como parte de una expresión que determina la posición del fin de la
   definición.

#    The set up for @c{count-words-in-defun} takes shape rapidly: first we move
#    point to the beginning of the definition, then we create a local variable
#    to hold the count, and finally, we record the position of the end of the
#    definition so the @c{while} loop will know when to stop looping.
   La configuración para @c{contar-palabras-en-definicion} toma forma rápidamente:
   primero movemos el punto al principio de la definición, luego creamos
   una variable local para almacenar el conteo, y finalmente, registramos la
   posición del final de la definición para que el bucle @c{while} sepa cuando
   terminar.

#    The code looks like this:
   El código es asi:

#    ..src > elisp
#      (beginning-of-defun)
#      (let ((count 0)
#            (end (save-excursion (end-of-defun) (point))))
#    < src..
   ..src > elisp
     (beginning-of-defun)
     (let ((cuenta 0)
           (fin (save-excursion (end-of-defun) (point))))
   < src..

#    The code is simple. The only slight complication is likely to concern
#    @c{end}: it is bound to the position of the end of the definition by a
#    @c{save-excursion} expression that returns the value of point after
#    @c{end-of-defun} temporarily moves it to the end of the definition.
   El código es simple. Es probable que la única pequeña complicación este en
   @c{fin}, que se vincula a la posición del fin de la definición con una expresión
   @c{save-excursion} que devuelve el valor de @c{end-of-defun} que a su vez
   mueve temporalmente el punto al final de la definición.

#    The second part of the @c{count-words-in-defun}, after the set up, is the
#    @c{while} loop.
   La segunda parte de @c{contar-palabras-en-definicion}, después de la
   configuración, es el bucle @c{while}.

#    The loop must contain an expression that jumps point forward word by word
#    and symbol by symbol, and another expression that counts the jumps. The
#    true-or-false-test for the @c{while} loop should test true so long as
#    point should jump forward, and false when point is at the end of the
#    definition. We have already redefined the regular expression for this, so
#    the loop is straightforward:
   El bucle debe contener una expresión que mueva el punto hacia adelante
   palabra por palabra y símbolo por símbolo, y otra expresión que cuente los
   saltos. La prueba-verdadero-o-falso del bucle @c{while} debe ser
   verdadero siempre y cuando el punto salte hacia adelante, y falso
   si el punto esta al final de la definición. Ya hemos redefinido la expresión
   regular para esto, así que el bucle es sencillo:

#    ..src > elisp
#      (while (and (< (point) end)
#                  (re-search-forward
#                   "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*" end t))
#        (setq count (1+ count)))
#    < src..
   ..src > elisp
     (while (and (< (point) fin)
                 (re-search-forward
                  "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*" fin t)
       (setq cuenta (1+ cuenta)))
   < src..

#    The third part of the function definition returns the count of words and
#    symbols. This part is the last expression within the body of the @c{let}
#    expression, and can be, very simply, the local variable @c{count}, which
#    when evaluated returns the count.
   La tercera parte de la definición devuelve el numero de palabras y
   símbolos. Esta parte es la última expresión dentro del cuerpo de la expresión
   @c{let}, y puede ser, simplemente la variable local @c{cuenta}, que al
   evaluarse devuelve el conteo.

#    Put together, the @c{count-words-in-defun} definition looks like this:
   En conjunto, la definición @c{contar-palabras-en-definicion} luce así:

#    ..src > elisp
#      (defun count-words-in-defun ()
#        "Return the number of words and symbols in a defun."
#        (beginning-of-defun)
#        (let ((count 0)
#              (end (save-excursion (end-of-defun) (point))))
#          (while
#              (and (< (point) end)
#                   (re-search-forward
#                    "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*"
#                    end t))
#            (setq count (1+ count)))
#          count))
#    < src..
   ..src > elisp
     (defun contar-palabras-en-definicion ()
       "Devuelve el número de palabras y símbolos en una defun."
       (beginning-of-defun)
       (let ((cuenta 0)
             (fin (save-excursion (end-of-defun) (point))))
         (while
             (and (< (point) fin)
                  (re-search-forward
                   "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*"
                   fin t))
           (setq cuenta (1+ cuenta)))
         cuenta))
   < src..

#    How to test this?  The function is not interactive, but it is easy to put
#    a wrapper around the function to make it interactive; we can use almost
#    the same code as for the recursive version of @c{count-words-example}:
   ¿Cómo probar esto? La función no es interactiva, pero es fácil poner
   un envoltorio alrededor de la función para hacerla interactiva; podemos
   usar casi el mismo código que el de la versión recursiva de
   @c{count-words-example}:

#    ..src > elisp
   ..src > elisp
#      ;;; Interactive version.
     ;;; Versión Interactiva.
#      (defun count-words-defun ()
     (defun contar-palabras-en-defun ()
#        "Number of words and symbols in a function definition."
       "Número de palabras y símbolos en una definición de función."
#        (interactive)
       (interactive)
#        (message
#         "Counting words and symbols in function definition ... ")
       (message
        "Contando palabras y símbolos en la definición de función ... ")
#        (let ((count (count-words-in-defun)))
       (let ((cuenta (contar-palabras-en-definicion)))
#          (cond
         (cond
#           ((zerop count)
          ((zerop cuenta)
#            (message
#             "The definition does NOT have any words or symbols."))
           (message
            "La definición NO tiene palabras o símbolos."))
#           ((= 1 count)
          ((= 1 cuenta)
#            (message
#             "The definition has 1 word or symbol."))
           (message
            "La definición tiene 1 palabra o símbolo."))
#           (t
          (t
#            (message
#             "The definition has %d words or symbols." count)))))
           (message
            "La definición tiene %d palabras o símbolos." cuenta)))))
#    < src..
   < src..

#    Let's re-use @k{C-c =} as a convenient keybinding:
   Reutilicemos @k{C-c =} como un conveniente atajo:

#    ..src > elisp
#      (global-set-key "\C-c=" 'count-words-defun)
#    < src..
   ..src > elisp
     (global-set-key "\C-c=" 'contar-palabras-en-defun)
   < src..

#    Now we can try out @c{count-words-defun}: install both
#    @c{count-words-in-defun} and @c{count-words-defun}, and set the
#    keybinding, and then place the cursor within the following definition:
   Ahora podemos probar @c{contar-palabras-en-defun}: instala ambas funciones
   @c{contar-palabras-en-definicion} y @c{contar-palabras-en-defun}, y asigna el atajo,
   luego coloca el cursor dentro de la siguiente definición:

#    ..src > elisp
#      (defun multiply-by-seven (number)
#        "Multiply NUMBER by seven."
#        (* 7 number))
#    < src..
   ..src > elisp
     (defun multiplicar-por-siete (numero)
       "Multiplicar NUMERO por siete."
       (* 7 numero))
   < src..

#    Success!  The definition has 10 words and symbols.
   ¡Éxito! La definición tiene 10 palabras y símbolos.

#    The next problem is to count the numbers of words and symbols in several
#    definitions within a single file.
   El siguiente problema es contar el numero de palabras y símbolos en
   varias definiciones en un mismo fichero.

# ** Count Several @c{defuns} Within a File
** Contar varias @c{defuns} dentro de un fichero

#    A file such as @f{simple.el} may have a hundred or more function
#    definitions within it. Our long term goal is to collect statistics on
#    many files, but as a first step, our immediate goal is to collect
#    statistics on one file.
   Un fichero como @f{simple.el} puede tener cientos o más definiciones dentro
   de el. Nuestro objetivo a largo plazo es recopilar estadísticas de muchos ficheros,
   pero como primer paso, nuestro objetivo inmediato es recoger estadísticas de
   un solo fichero.

#    The information will be a series of numbers, each number being the length
#    of a function definition. We can store the numbers in a list.
   La información será una serie de números, siendo cada número la longitud de
   una definición de función. Podemos almacenar los números en una lista.

#    We know that we will want to incorporate the information regarding one
#    file with information about many other files; this means that the function
#    for counting definition lengths within one file need only return the list
#    of lengths. It need not and should not display any messages.
   Sabemos que querremos incorporar la información relativa a un fichero
   con información sobre muchos otros ficheros; esto significa que la
   función para contar la longitudes de las definiciones solo necesita
   devolver la lista de longitudes. No necesita ni debe mostrar ningun mensaje.

#    The word count commands contain one expression to jump point forward word
#    by word and another expression to count the jumps. The function to return
#    the lengths of definitions can be designed to work the same way, with one
#    expression to jump point forward definition by definition and another
#    expression to construct the lengths' list.
   Los comandos de conteo de palabras contienen una expresión para mover el punto
   palabra a palabra y otra expresión para contar los saltos. La función
   para devolver la longitud de las definiciones puede ser diseñada para trabajar
   del mismo modo, con una expresión para mover el punto hacia adelante definición
   por definición y otra expresión para construir la lista de longitudes.

#    This statement of the problem makes it elementary to write the function
#    definition. Clearly, we will start the count at the beginning of the
#    file, so the first command will be @c{(goto-char (point-min))}. Next, we
#    start the @c{while} loop; and the true-or-false test of the loop can be a
#    regular expression search for the next function definition––so long as the
#    search succeeds, point is moved forward and then the body of the loop is
#    evaluated. The body needs an expression that constructs the lengths'
#    list.  @c{cons}, the list construction command, can be used to create the
#    list. That is almost all there is to it.
   Esta afirmacion del problema hace que sea elemental escribir la definición de
   función. Claramente, empezaremos el conteo al principio del fichero, por lo
   que el primer comando será @c{(goto-char (point-min))}. Lo siguiente, es
   iniciar el bucle @c{while}; y la puerba verdadero-o-falso del bucle puede ser
   una regexp para la siguiente definición de función––siempre y cuando la
   búsqueda tenga éxito, el punto se movera hacia adelante y luego se evaluara
   el cuerpo del bucle. El cuerpo necesita una expresión que construya la lista
   de longitudes. @c{cons}, el comando de construccion de listas, puede
   utilizarce para crear la lista. Esto es casi todo lo que hay.

#    Here is what this fragment of code looks like:
   Este fragmento de código tendria el siguiente aspecto:

#    ..src > elisp
#      (goto-char (point-min))
#      (while (re-search-forward "^(defun" nil t)
#        (setq lengths-list
#              (cons (count-words-in-defun) lengths-list)))
#    < src..
   ..src > elisp
     (goto-char (point-min))
     (while (re-search-forward "^(defun" nil t)
       (setq lista-de-longitudes
             (cons (contar-palabras-en-definicion) lista-de-longitudes)))
   < src..

#    What we have left out is the mechanism for finding the file that contains
#    the function definitions.
   Dejamos fuera el mecanismo para encontrar el fichero que contiene las
   definiciones de función.

#    In previous examples, we either used this, the Info file, or we switched
#    back and forth to some other buffer, such as the @f{*scratch*} buffer.
   En ejemplos anteriores, usabamos este fichero, o el fichero Info, o cambiamos
   de un búfer a otro, como el búfer @f{*scratch*}.

#    Finding a file is a new process that we have not yet discussed.
   Encontrar un fichero es un nuevo proceso que aun no hemos discutido.

# ** Find a File
** Encontrar un fichero

#    To find a file in Emacs, you use the @k{C-x C-f} @%c(find-file) command.
#    This command is almost, but not quite right for the lengths problem.
   Para encontrar un fichero en Emacs, se usa el comando @k{C-x C-f}
   @%c(find-file). Este comando es casi, pero no del todo adecuado para el
   problema de las longitudes.

#    Let's look at the source for @c{find-file}:
   Veamos el codigo fuente de @c{find-file}:

#    ..src > elisp
#      (defun find-file (filename)
#        "Edit file FILENAME.
#      Switch to a buffer visiting file FILENAME,
#      creating one if none already exists."
#        (interactive "FFind file: ")
#        (switch-to-buffer (find-file-noselect filename)))
#    < src..
   ..src > elisp
     (defun find-file (filename)
       "Edita el fichero FILENAME.
     Cambia a un búfer visitando el fichero FILENAME,
     creando uno si no existe ya."
       (interactive "FFind file: ")
       (switch-to-buffer (find-file-noselect filename)))
   < src..

#    (The most recent version of the @c{find-file} function definition permits
#    you to specify optional wildcards to visit multiple files; that makes the
#    definition more complex and we will not discuss it here, since it is not
#    relevant. You can see its source using either @k{M-.} @%c(find-tag) or
#    @k{C-h f} @%c(describe-function).)
   (La definición de la versión más reciente de @c{find-file} permite
   especificar comodines especiales para visitar múltiples ficheros; que hacen la
   definición más compleja y no la discutiremos aquí, ya que no es relevante. Se
   puede ver el codigo usando @k{M-.} @%c(find-tag) o @k{C-h f} @%c(describe-function).)

#    The definition I am showing possesses short but complete documentation and
#    an interactive specification that prompts you for a file name when you use
#    the command interactively. The body of the definition contains two
#    functions, @c{find-file-noselect} and @c{switch-to-buffer}.
   La definición que estoy mostrando posee una documentación corta, pero
   completa y una expresion interactiva que pide un nombre de fichero
   cuando se usa el comando interactivamente. El cuerpo de la definición
   contiene dos funciones, @c{find-file-noselect} y @c{switch-to-buffer}.

#    According to its documentation as shown by @k{C-h f} (the
#    @c{describe-function} command), the @c{find-file-noselect} function reads
#    the named file into a buffer and returns the buffer.  (Its most recent
#    version includes an optional wildcards argument, too, as well as another
#    to read a file literally and an other you suppress warning messages.
#    These optional arguments are irrelevant.)
   De acuerdo con su documentación, tal y como se muestra con @k{C-h f} (el comando
   @c{describe-function}), la función @c{find-file-noselect} lee el fichero
   nombrado en un búfer y devuelve el búfer. (Su versión más
   reciente incluye un argumento comodín opcional, así como otro para leer un
   fichero literalmente y otro para suprimir mensajes de advertencia. Estos
   argumentos opcionales son irrelevantes.)

#    However, the @c{find-file-noselect} function does not select the buffer in
#    which it puts the file. Emacs does not switch its attention (or yours if
#    you are using @c{find-file-noselect}) to the selected buffer. That is
#    what @c{switch-to-buffer} does: it switches the buffer to which Emacs
#    attention is directed; and it switches the buffer displayed in the window
#    to the new buffer. We have discussed buffer switching elsewhere.  (See
#    Section @l{#Switching Buffers}.)
   Sin embargo, la función @c{find-file-noselect} no selecciona el búfer en
   el que se pone el fichero. Emacs no cambia su atención (o la tuya si estás
   usando @c{find-file-noselect}) al búfer seleccionado. Esto es lo que hace
   @c{switch-to-buffer}: cambia el búfer al que se dirige la
   atención de Emacs; y cambia el búfer mostrado en la ventana al nuevo
   búfer. Hemos discutido el cambiando de búfer en otra parte. (Consulta la Seccion
   @l{#Cambiando búfers}.)

#    In this histogram project, we do not need to display each file on the
#    screen as the program determines the length of each definition within it.
#    Instead of employing @c{switch-to-buffer}, we can work with
#    @c{set-buffer}, which redirects the attention of the computer program to a
#    different buffer but does not redisplay it on the screen. So instead of
#    calling on @c{find-file} to do the job, we must write our own expression.
   En este proyecto de histograma, no necesitamos mostrar cada fichero en la
   pantalla ya que el programa determina el tamaño de cada definición dentro de
   el. En lugar de emplear @c{switch-to-buffer}, podemos trabajar con
   @c{set-buffer}, que redirige la atención del programa a un búfer diferente,
   pero no lo muestra en pantalla. Así en vez llamar a @c{find-file} para hacer
   el trabajo, debemos escribir nuestra propia expresión.

#    The task is easy: use @c{find-file-noselect} and @c{set-buffer}.
   La tarea es fácil: usar @c{find-file-noselect} y @c{set-buffer}.

# ** @c{lengths-list-file} in Detail
** @c{lista-de-longitudes-en-fichero} en detalle

#    The core of the @c{lengths-list-file} function is a @c{while} loop
#    containing a function to move point forward ‘defun by defun’ and a
#    function to count the number of words and symbols in each defun. This
#    core must be surrounded by functions that do various other tasks,
#    including finding the file, and ensuring that point starts out at the
#    beginning of the file. The function definition looks like this:
   El núcleo de la función @c{lista-de-longitudes-en-fichero} es un bucle
   @c{while} que contiene una función para mover el punto hacia delante ‘defun a
   defun’ y una función para contar el número de palabras y símbolos en cada
   definicion de funcion. Este núcleo debe ser rodeado por funciones que
   realizan otras tareas varias, incluyendo encontrar el fichero, y asegurarse
   que el punto empieza al principio del fichero. La definición de la función se
   ve asi:

#    ..src > elisp
   ..src > elisp
#      (defun lengths-list-file (filename)
     (defun lista-de-longitudes-en-fichero (nombre-de-fichero)
#        "Return list of definitions' lengths within FILE.
#      The returned list is a list of numbers.
#      Each number is the number of words or
#      symbols in one function definition."
       "Devuelve la lista de longitudes de las definiciones dentro de NOMBRE-DE-FICHERO.
     La lista devuelta es una lista de números.
     Cada número es el número de palabras o
     símbolos en una definición."
#        (message "Working on `%s' ... " filename)
       (message "Trabajando en `%s' ... " nombre-de-fichero)
#        (save-excursion
#          (let ((buffer (find-file-noselect filename))
#                (lengths-list))
       (save-excursion
         (let ((buffer (find-file-noselect nombre-de-fichero))
               (lista-de-longitudes))
#            (set-buffer buffer)
#            (setq buffer-read-only t)
#            (widen)
           (set-buffer buffer)
           (setq buffer-read-only t)
           (widen)
#            (goto-char (point-min))
           (goto-char (point-min))
#            (while (re-search-forward "^(defun" nil t)
           (while (re-search-forward "^(defun" nil t)
#              (setq lengths-list
#                    (cons (count-words-in-defun) lengths-list)))
#            (kill-buffer buffer)
             (setq lista-de-longitudes
                   (cons (contar-palabras-en-definicion) lista-de-longitudes)))
#            lengths-list)))
           (kill-buffer buffer)
           lista-de-longitudes)))
#    < src..
   < src..

#    The function is passed one argument, the name of the file on which it will
#    work. It has four lines of documentation, but no interactive
#    specification. Since people worry that a computer is broken if they don't
#    see anything going on, the first line of the body is a message.
   A la función se le pasa un argumento, el nombre del fichero en el que
   trabajará. Tiene cuatro líneas de documentación, pero ninguna especificacion
   interactiva. Ya que a la gente le preocupa que un ordenador se estropee si
   no ve nada, la primera línea del cuerpo es un mensaje de aviso.

#    The next line contains a @c{save-excursion} that returns Emacs's attention
#    to the current buffer when the function completes. This is useful in case
#    you embed this function in another function that presumes point is
#    restored to the original buffer.
   La siguiente línea contiene un @c{save-excursion} que devuelve la atencion de
   Emacs al búfer actual cuando la función se completa. Esto es útil
   en caso de incorporar esta función dentro de otra función que suponga que el punto
   se restaura al búfer original.

#    In the varlist of the @c{let} expression, Emacs finds the file and binds
#    the local variable @c{buffer} to the buffer containing the file. At the
#    same time, Emacs creates @c{lengths-list} as a local variable.
   En la varlist de la expresión @c{let}, Emacs busca el fichero y enlaza
   la variable local @c{buffer} al búfer que contiene el fichero. Al mismo
   tiempo, Emacs crea @c{lista-de-longitudes} como una variable local.

#    Next, Emacs switches its attention to the buffer.
   A continuacion, Emacs cambia su atención al búfer.

#    In the following line, Emacs makes the buffer read-only. Ideally, this
#    line is not necessary. None of the functions for counting words and
#    symbols in a function definition should change the buffer. Besides, the
#    buffer is not going to be saved, even if it were changed. This line is
#    entirely the consequence of great, perhaps excessive, caution. The reason
#    for the caution is that this function and those it calls work on the
#    sources for Emacs and it is inconvenient if they are inadvertently
#    modified. It goes without saying that I did not realize a need for this
#    line until an experiment went awry and started to modify my Emacs source
#    files…
   En la siguiente línea, Emacs hace que el búfer sea de solo lectura.
   Idealmente, esta línea no es necesaria. Ninguna de las funciones para contar
   palabras y símbolos en una definición de función debe cambiar el búfer.
   Ademas, el búfer no va a guardarse, incluso si se ha modificado. Esta línea
   es enteramente la consecuencia de una gran cautela, quizás excesiva. La razón
   de la precaución es que esta función y aquellas a las que llama trabajaran en
   el codigo fuente de Emacs y es un inconveniente si se modifican de
   forma inadvertida. No hace falta decir que no me di cuenta de la necesidad de
   esta línea hasta que un experimento salio mal y empezó a modificar mis
   ficheros…

#    Next comes a call to widen the buffer if it is narrowed. This function is
#    usually not needed––Emacs creates a fresh buffer if none already exists;
#    but if a buffer visiting the file already exists Emacs returns that one.
#    In this case, the buffer may be narrowed and must be widened. If we
#    wanted to be fully ‘user-friendly’, we would arrange to save the
#    restriction and the location of point, but we won't.
   Luego viene una llamada para extender el búfer si esta reducido. Esta función
   normalmente es innecesaria––Emacs crea un búfer nuevo si no existe ninguno;
   pero si hay un búfer visitando el fichero, Emacs devuelve ese búfer. En este
   caso, el búfer puede estar reducido y debe extenderse. Si quisieramos ser
   completamente ‘amigables con el usuario’, nos encargariamos de guardar la
   restricción y la ubicacion del punto, pero no lo haremos.

#    The @c{(goto-char (point-min))} expression moves point to the beginning of
#    the buffer.
   La expresión @c{(goto-char (point-min))} mueve el punto al principio del
   búfer.

#    Then comes a @c{while} loop in which the ‘work’ of the function is carried
#    out. In the loop, Emacs determines the length of each definition and
#    constructs a lengths' list containing the information.
   Luego viene un bucle @c{while} en el que se realiza el ‘trabajo’ de la
   función. En el bucle, Emacs determina la longitud de cada definición y
   construye una lista de longitudes que contiene la información.

#    Emacs kills the buffer after working through it. This is to save space
#    inside of Emacs. My version of GNU Emacs 19 contained over 300 source
#    files of interest; GNU Emacs 22 contains over a thousand source files.
#    Another function will apply @c{lengths-list-file} to each of the files.
   Emacs mata el búfer después de trabajar a través de el. Esto es para ahorrar
   espacio dentro de Emacs. Mi versión de GNU Emacs 19 contenía 300 ficheros
   de codigo fuente de interés; GNU Emacs 22 contiene mas de mil ficheros de codigo
   fuente. Otra función aplicará @c{lista-de-longitudes-en-fichero} a cada uno de los
   ficheros.

#    Finally, the last expression within the @c{let} expression is the
#    @c{lengths-list} variable; its value is returned as the value of the whole
#    function.
   Finalmente, la última expresión dentro de la expresión @c{let} es la variable
   @c{lista-de-longitudes}; su valor se devuelve como el valor de toda la función.

#    You can try this function by installing it in the usual fashion. Then
#    place your cursor after the following expression and type @k{C-x C-e}
#    @%c(eval-last-sexp).
   Se puede probar esta función instalándola de la forma habitual. A
   continuacion coloca tu cursor después de la siguiente expresión y presiona
   @k{C-x C-e} @%c(eval-last-sexp).

#    ..src > elisp
#      (lengths-list-file
#       "/usr/local/share/emacs/22.1.1/lisp/emacs-lisp/debug.el")
#    < src..
   ..src > elisp
     (lista-de-longitudes-en-fichero
      "/usr/local/share/emacs/22.1.1/lisp/emacs-lisp/debug.el")
   < src..

#    You may need to change the pathname of the file; the one here is for GNU
#    Emacs version 22.1.1. To change the expression, copy it to the
#    @f{*scratch*} buffer and edit it.
   Puede que necesites cambiar la ruta del fichero; la de aqui es para GNU
   Emacs versión 22.1.1. Para cambiar la expresión, cópiala al búfer
   @f{*scratch*} y edítala.

#    Also, to see the full length of the list, rather than a truncated
#    version, you may have to evaluate the following:
   Ademas, para ver el la longitud completa de la lista, en lugar de una versión
   truncada es posible tener que evaluar lo siguiente:

#    ..src > elisp
#      (custom-set-variables '(eval-expression-print-length nil))
#    < src..
   ..src > elisp
     (custom-set-variables '(eval-expression-print-length nil))
   < src..

#    (See Section @l{#Specifying Variables using @c{defcustom}}. Then evaluate
#    the @c{lengths-list-file} expression.)
   (Consulta la Seccion @l{#Especificar variables usando @c{defcustom}}. A contituacion
   evalúa la expresión @c{lista-de-longitudes-en-fichero}.)

#    The lengths' list for @f{debug.el} takes less than a second to produce and
#    looks like this in GNU Emacs 22:
   La lista de longitudes para @f{debug.el} tarda menos de un segundo en
   producirse y se ve asi en GNU Emacs 22:

#    ..srci > elisp
#      (83 113 105 144 289 22 30 97 48 89 25 52 52 88 28 29 77 49 43 290 232 587)
#    < srci..
   ..srci > elisp
     (83 113 105 144 289 22 30 97 48 89 25 52 52 88 28 29 77 49 43 290 232 587)
   < srci..

#    Using my old machine, the version 19 lengths' list for @f{debug.el} took
#    seven seconds to produce and looked like this:
   Usando mi vieja máquina, con la versión 19 tambien con @f{debug.el}
   demora siete segundos en producir esto:

#    ..srci > elisp
#      (75 41 80 62 20 45 44 68 45 12 34 235)
#    < srci..
   ..srci > elisp
     (75 41 80 62 20 45 44 68 45 12 34 235)
   < srci..

#    The newer version of @f{debug.el} contains more defuns than the earlier
#    one; and my new machine is much faster than the old one.
   La versión nueva de @f{debug.el} contiene más defuns que la anterior; y
   mi nueva máquina es mucho más rápida que la vieja.

#    Note that the length of the last definition in the file is first in the
#    list.
   Ten en cuenta que el tamaño de la última definición en el fichero es la primera
   de la lista.

# ** Count Words in @c{defuns} in Different Files
** Contar palabras en @c{defuns} en diferentes ficheros

#    In the previous section, we created a function that returns a list of the
#    lengths of each definition in a file. Now, we want to define a function
#    to return a master list of the lengths of the definitions in a list of
#    files.
   En la sección anterior, creamos una función que devuelve una lista de las
   longitudes de cada definición en un fichero. Ahora, queremos definir una
   función para devolver una lista maestra de las longitudes de las definiciones
   en una lista de ficheros.

#    Working on each of a list of files is a repetitious act, so we can use
#    either a @c{while} loop or recursion.
   Trabajar en cada una de las listas de ficheros es un acto repetitivo,
   por lo que podemos usar un bucle @c{while} o recursión.

#    The design using a @c{while} loop is routine. The argument passed the
#    function is a list of files. As we saw earlier (see Section @l{#A
#    @c{while} Loop and a List}), you can write a @c{while} loop so that the
#    body of the loop is evaluated if such a list contains elements, but to
#    exit the loop if the list is empty. For this design to work, the body of
#    the loop must contain an expression that shortens the list each time the
#    body is evaluated, so that eventually the list is empty. The usual
#    technique is to set the value of the list to the value of the @c{cdr} of
#    the list each time the body is evaluated.
   El diseño utilizando un bucle @c{while} es rutinario. El argumento que se
   pasa a la función es una lista de ficheros. Como vimos anteriormente (Ver
   Sección @l{#Un bucle @c{while} y una lista}), se puede escribir un bucle
   @c{while} de un modo que el cuerpo del bucle se evalue si tal lista
   contiene elementos, pero que deba salir del bucle si la lista está
   vacía. Para que este diseño funcione, el cuerpo del bucle debe contener una
   expresión que acorte la lista con cada evaluacion del cuerpo, de modo que
   finalmente la lista esté vacía. La técnica usual es asignar el valor de la
   lista al valor del @c{cdr} de la lista cada vez que se evalua el cuerpo.

#    The template looks like this:
   La plantilla se ve así:

#    ..src > elisp
#      (while test-whether-list-is-empty
#        body…
#        set-list-to-cdr-of-list)
#    < src..
   ..src > elisp
     (while comprobar-si-la-lista-esta-vacia
       cuerpo…
       asignar-lista-al-cdr-de-la-lista)
   < src..

#    Also, we remember that a @c{while} loop returns @c{nil} (the result of
#    evaluating the true-or-false-test), not the result of any evaluation
#    within its body.  (The evaluations within the body of the loop are done
#    for their side effects.)  However, the expression that sets the lengths'
#    list is part of the body––and that is the value that we want returned by
#    the function as a whole. To do this, we enclose the @c{while} loop within
#    a @c{let} expression, and arrange that the last element of the @c{let}
#    expression contains the value of the lengths' list.  (See Section
#    @l{#Example with Incrementing Counter}.)
   Ademas, recordemos que un bucle @c{while} devuelve @c{nil} (el resultado
   de evaluar la prueba-verdadero-o-falso), no el resultado de ninguna evaluación
   dentro de su cuerpo. (Las evaluaciones dentro del cuerpo del bucle se hacen por
   sus efectos secundarios.) Sin embargo, la expresión que establece la lista de
   longitudes es parte del cuerpo––y ese es valor que queremos que devuelva
   la función como un todo. Para hacer esto, rodeamos el bucle @c{while} con
   una expresión @c{let}, y disponemos que el último elemento de la
   expresión @c{let} contiene el valor de lista de longitudes. (Consulta la Seccion
   @l{#Ejemplo con contador incremental}.)

#    These considerations lead us directly to the function itself:
   Estas consideraciones nos llevan directamente a la función en sí:

#    ..src > elisp
   ..src > elisp
#      ;;; Use while loop.
     ;;; Usar bucle while.
#      (defun lengths-list-many-files (list-of-files)
     (defun lista-de-longitudes-de-muchos-ficheros (lista-de-ficheros)
#        "Return list of lengths of defuns in LIST-OF-FILES."
       "Devuelve la lista de longitudes de defuns en LISTA-DE-FICHEROS."
#        (let (lengths-list)
       (let (lista-de-longitudes)

#      ;;; true-or-false-test
     ;;; prueba-verdadero-o-falso
#          (while list-of-files
#            (setq lengths-list
#                  (append
#                   lengths-list
         (while lista-de-ficheros
           (setq lista-de-longitudes
                 (append
                  lista-de-longitudes

#      ;;; Generate a lengths' list.
     ;;; Genera una lista de longitudes.
#                   (lengths-list-file
#                    (expand-file-name (car list-of-files)))))
                  (lista-de-longitudes-en-fichero
                   (expand-file-name (car lista-de-ficheros)))))

#      ;;; Make files' list shorter.
     ;;; Reducir la lista de ficheros.
#            (setq list-of-files (cdr list-of-files)))
           (setq lista-de-ficheros (cdr lista-de-ficheros)))

#      ;;; Return final value of lengths' list.
     ;;; Devuelve el valor final de la lista de longitudes.
#          lengths-list))
         lista-de-longitudes))
#    < src..
   < src..

#    @c{expand-file-name} is a built-in function that converts a file name to
#    the absolute, long, path name form. The function employs the name of the
#    directory in which the function is called.
   @c{expand-file-name} es una función nativa que convierte el nombre de un
   fichero a su nombre de ruta absoluta. La función emplea el nombre
   del directorio en el que se llama la función.

#    Thus, if @c{expand-file-name} is called on @c{debug.el} when Emacs is
#    visiting the @f{/usr/local/share/emacs/22.1.1/lisp/emacs-lisp/} directory,
   De este modo, si se llama a @c{expand-file-name} dentro de @c{debug.el} cuando
   Emacs está visitando el directorio @f{/usr/local/share/emacs/22.1.1/lisp/emacs-lisp/}

#    ..example >
#      debug.el
#    < example..
   ..example >
     debug.el
   < example..

#    becomes
   se convierte en

#    ..example >
#      /usr/local/share/emacs/22.1.1/lisp/emacs-lisp/debug.el
#    < example..
   ..example >
     /usr/local/share/emacs/22.1.1/lisp/emacs-lisp/debug.el
   < example..

#    The only other new element of this function definition is the as yet
#    unstudied function @c{append}, which merits a short section for itself.
   El único otro nuevo elemento de esta definición de función es la todavía no
   estudiada función @c{append}, que merece una breve sección.

# *** The @c{append} Function
*** La función @c{append}

#     The @c{append} function attaches one list to another. Thus,
    La función @c{append} une una lista a otra. De este modo,

#     ..src > elisp
#       (append '(1 2 3 4) '(5 6 7 8))
#     < src..
    ..src > elisp
      (append '(1 2 3 4) '(5 6 7 8))
    < src..

#     produces the list
    produce la lista

#     ..src > elisp
#       (1 2 3 4 5 6 7 8)
#     < src..
    ..src > elisp
      (1 2 3 4 5 6 7 8)
    < src..

#     This is exactly how we want to attach two lengths' lists produced by
#     @c{lengths-list-file} to each other. The results contrast with @c{cons},
    Asi es exactamente cómo queremos unir dos listas de longitudes
    producidas por @c{lista-de-longitudes-en-fichero} entre si. Los resultados
    contrastan con @c{cons},

#     ..src > elisp
#       (cons '(1 2 3 4) '(5 6 7 8))
#     < src..
    ..src > elisp
      (cons '(1 2 3 4) '(5 6 7 8))
    < src..

#     which constructs a new list in which the first argument to @c{cons}
#     becomes the first element of the new list:
    que construye una nueva lista en la que el primer argumento de @c{cons}
    se convierte en el primer elemento de la nueva lista:

#     ..src > elisp
#       ((1 2 3 4) 5 6 7 8)
#     < src..
    ..src > elisp
      ((1 2 3 4) 5 6 7 8)
    < src..

# ** Recursively Count Words in Different Files
** Contar palabras recursivamente en diferentes ficheros

#    Besides a @c{while} loop, you can work on each of a list of files with
#    recursion. A recursive version of @c{lengths-list-many-files} is short
#    and simple.
   Ademas de un bucle @c{while}, podemos trabajar en cada lista de ficheros con
   recursión. Una versión recursiva de @c{lista-de-longitudes-de-muchos-ficheros}
   es corta y simple.

#    The recursive function has the usual parts: the ‘do-again-test’, the
#    ‘next-step-expression’, and the recursive call. The ‘do-again-test’
#    determines whether the function should call itself again, which it will do
#    if the @c{list-of-files} contains any remaining elements; the
#    ‘next-step-expression’ resets the @c{list-of-files} to the @c{cdr} of
#    itself, so eventually the list will be empty; and the recursive call calls
#    itself on the shorter list. The complete function is shorter than this
#    description!
   La función recursiva tiene las partes usuales: la ‘prueba-hazlo-de-nuevo’, la
   ‘expresion-del-siguiente-paso’, y la llamada recursiva. La
   ‘prueba-hazlo-de-nuevo’ determina si la función debe volver a llamarse a si
   misma, lo que hará si la @c{lista-de-ficheros} contiene algun elemento
   restante; la ‘expresion-del-siguiente-paso’ reasigna la @c{lista-de-ficheros}
   con su mismo @c{cdr}, por lo que eventualmente la lista estara vacía; y la
   llamada recursiva se llamara a si misma en la lista mas corta. ¡La función
   completa es mas corta que esta descripción!

#    ..src > elisp
#      (defun recursive-lengths-list-many-files (list-of-files)
#        "Return list of lengths of each defun in LIST-OF-FILES."
#        (if list-of-files                     ; do-again-test
#            (append
#             (lengths-list-file
#              (expand-file-name (car list-of-files)))
#             (recursive-lengths-list-many-files
#              (cdr list-of-files)))))
#    < src..
   ..src > elisp
     (defun lista-de-longitudes-de-muchos-ficheros-recursiva (lista-de-ficheros)
       "Devuelve la lista de longitudes de cada defun en LISTA-DE-FICHEROS."
       (if lista-de-ficheros                    ; prueba-hazlo-de-nuevo
           (append
            (lista-de-longitudes-en-fichero
             (expand-file-name (car lista-de-ficheros)))
            (lista-de-longitudes-de-muchos-ficheros-recursiva
             (cdr lista-de-ficheros)))))
   < src..

#    In a sentence, the function returns the lengths' list for the first of the
#    @c{list-of-files} appended to the result of calling itself on the rest of
#    the @c{list-of-files}.
   En una frase, la función devuelve la lista de longitudes para la
   primer @c{lista-de-ficheros} adjunta al resultado de llamarse así misma al
   resto de la @c{lista-de-ficheros}.

#    Here is a test of @c{recursive-lengths-list-many-files}, along with the
#    results of running @c{lengths-list-file} on each of the files
#    individually.
   Aquí hay una prueba de @c{lista-de-longitudes-de-muchos-ficheros-recursiva},
   junto con los resultados de ejecutar @c{lista-de-longitudes-en-fichero} en cada
   uno de los ficheros individualmente.

#    Install @c{recursive-lengths-list-many-files} and @c{lengths-list-file},
#    if necessary, and then evaluate the following expressions. You may need
#    to change the files' pathnames; those here work when this Info file and
#    the Emacs sources are located in their customary places. To change the
#    expressions, copy them to the @f{*scratch*} buffer, edit them, and then
#    evaluate them.
   Instala @c{lista-de-longitudes-de-muchos-ficheros-recursiva} y
   @c{lista-de-longitudes-en-fichero}, y luego evalúa las siguientes
   expresiones. Es posible que necesites cambiar las rutas a los ficheros; las
   que aquí se incluyen funcionan cuando las fuentes de Emacs se encuentran
   en sus lugares habituales. Para cambiar las expresiones, cópialas al búfer
   @f{*scratch*}, edítalas y evalualas.

#    (These results are for files from Emacs version 22.1.1; files from other
#    versions of Emacs may produce different results.)
   (Estos resultados son para ficheros de la versión 22.1.1; los ficheros
   de otras versiones puede producir resultados diferentes.)

#    ..srci > elisp
#      > (cd "/usr/local/share/emacs/22.1.1/")
#      > (lengths-list-file "./lisp/macros.el")
#      (283 263 480 90)
#      > (lengths-list-file "./lisp/mail/mailalias.el")
#      (38 32 29 95 178 180 321 218 324)
#      > (lengths-list-file "./lisp/makesum.el")
#      (85 181)
#      > (recursive-lengths-list-many-files
#      ^  '("./lisp/macros.el"
#      ^    "./lisp/mail/mailalias.el"
#      ^    "./lisp/makesum.el"))
#      (283 263 480 90 38 32 29 95 178 180 321 218 324 85 181)
#    < srci..
   ..srci > elisp
     > (cd "/usr/local/share/emacs/22.1.1/")
     > (lista-de-longitudes-en-fichero "./lisp/macros.el")
     (283 263 480 90)
     > (lista-de-longitudes-en-fichero "./lisp/mail/mailalias.el")
     (38 32 29 95 178 180 321 218 324)
     > (lista-de-longitudes-en-fichero "./lisp/makesum.el")
     (85 181)
     > (lista-de-longitudes-de-muchos-ficheros-recursiva
     ^  '("./lisp/macros.el"
     ^    "./lisp/mail/mailalias.el"
     ^    "./lisp/makesum.el"))
     (283 263 480 90 38 32 29 95 178 180 321 218 324 85 181)
   < srci..

#    The @c{recursive-lengths-list-many-files} function produces the output we
#    want.
   La función @c{lista-de-longitudes-de-muchos-ficheros-recursiva} produce la salida que
   queremos.

#    The next step is to prepare the data in the list for display in a graph.
   El siguiente paso es preparar los datos de la lista para visualizarlos en un
   grafico.

# ** Prepare the Data for Display in a Graph
** Preparar los datos para visualizarlos en un grafico

#    The @c{recursive-lengths-list-many-files} function returns a list of
#    numbers. Each number records the length of a function definition. What
#    we need to do now is transform this data into a list of numbers suitable
#    for generating a graph. The new list will tell how many functions
#    definitions contain less than 10 words and symbols, how many contain
#    between 10 and 19 words and symbols, how many contain between 20 and 29
#    words and symbols, and so on.
   La función @c{lista-de-longitudes-de-muchos-ficheros-recursiva} devuelve una
   lista de números. Cada número registra la longitud de una definición de
   función. Lo que tenemos que hacer ahora es transformar estos datos en una
   lista de números adecuados para generar un grafico. La nueva lista dira
   cuántas definiciones de funcion contienen menos de 10 palabras y símbolos,
   cuantas entre 10 y 19, cuántas entre 20 y 29, y así sucesivamente.

#    In brief, we need to go through the lengths' list produced by the
#    @c{recursive-lengths-list-many-files} function and count the number of
#    defuns within each range of lengths, and produce a list of those numbers.
   En resumen, necesitamos revisar la lista de longitudes producida por la
   función @c{lista-de-longitudes-de-muchos-ficheros-recursiva} y contar el
   número de definiciones dentro de cada rango, y producir una lista de esos
   números.

#    Based on what we have done before, we can readily foresee that it should
#    not be too hard to write a function that ‘@c{cdr}s’ down the lengths'
#    list, looks at each element, determines which length range it is in, and
#    increments a counter for that range.
   Basado en lo que hemos hecho antes, podemos preveer que no sera demaciado difícil
   escribir una función que redusca la lista de longitudes con ‘@c{cdr}s’, mire
   cada elemento, determine en que rango de longitud esta, e incremente un
   contador para ese rango.

#    However, before beginning to write such a function, we should consider the
#    advantages of sorting the lengths' list first, so the numbers are ordered
#    from smallest to largest. First, sorting will make it easier to count the
#    numbers in each range, since two adjacent numbers will either be in the
#    same length range or in adjacent ranges. Second, by inspecting a sorted
#    list, we can discover the highest and lowest number, and thereby determine
#    the largest and smallest length range that we will need.
   Sin embargo, antes de empezar a escribir tal función, debemos
   considerar las ventajas de primero ordenar la lista de longitudes,
   de modo que los números se ordenen del más pequeño al más grande. En primer lugar,
   la ordenacion facilitara el conteo de los números en el mismo rango, ya que dos
   números adyacentes estaran en el mismo rango de longitud o en rangos
   adyacentes. Segundo, inspeccionando una lista ordenada, podemos descubrir
   el número mas alto y el mas bajo, y asi determinar el rango de longitud mas
   grande y mas pequeño que necesitaremos.

# **** Sorting Lists
*** Ordenando listas

#      Emacs contains a function to sort lists, called (as you might guess)
#      @c{sort}. The @c{sort} function takes two arguments, the list to be
#      sorted, and a predicate that determines whether the first of two list
#      elements is “less” than the second.
    Emacs contiene una función para ordenar listas, llamada (como se
    podría adivinar) @c{sort}. La función @c{sort} toma dos argumentos, la
    lista a ordenar, y un predicado que determina si el primero de dos
    elementos de la lista es “menor” que el segundo.

#      As we saw earlier (see Section @l{#Using the Wrong Type Object as an
#      Argument}), a predicate is a function that determines whether some
#      property is true or false. The @c{sort} function will reorder a list
#      according to whatever property the predicate uses; this means that
#      @c{sort} can be used to sort non-numeric lists by non-numeric
#      criteria––it can, for example, alphabetize a list.
    Como vimos anteriormente (Ver Sección @l{#Usando el tipo incorrecto de objeto
    como argumento}), un predicado es una función que determina si alguna
    propiedad es verdadera o falsa. La función @c{sort} reordenará una lista de
    acuerdo a cualquier propiedad que use el predicado; esto significa que
    @c{sort} puede usarse para ordenar listas no numéricas por un criterio no
    numérico––puede, por ejemplo, ordenar la lista alfabeticamente.

#      The @c{<} function is used when sorting a numeric list. For example,
    La función @c{<} se utiliza para ordena una lista numérica. Por ejemplo,

#      ..src > elisp
#        (sort '(4 8 21 17 33 7 21 7) '<)
#      < src..
    ..src > elisp
      (sort '(4 8 21 17 33 7 21 7) '<)
    < src..

#      produces this:
    produce esto:

#      ..src > elisp
#        (4 7 7 8 17 21 21 33)
#      < src..
    ..src > elisp
      (4 7 7 8 17 21 21 33)
    < src..

#      (Note that in this example, both the arguments are quoted so that the
#      symbols are not evaluated before being passed to @c{sort} as arguments.)
    (Ten en cuenta que en este ejemplo, ambos argumentos se citan para que no
    se evaluen los símbolos antes de pasarlos a @c{sort} como argumentos.)

#      Sorting the list returned by the @c{recursive-lengths-list-many-files}
#      function is straightforward; it uses the @c{<} function:
    Ordenar la lista devuelta por la función
    @c{lista-de-longitudes-de-muchos-ficheros-recursiva} es sencillo; utilizando
    la función @c{<}:

#      ..src > elisp
#        (sort
#         (recursive-lengths-list-many-files
#          '("./lisp/macros.el"
#            "./lisp/mailalias.el"
#            "./lisp/makesum.el"))
#         '<)
#      < src..
    ..src > elisp
      (sort
       (lista-de-longitudes-de-muchos-ficheros-recursiva
        '("./lisp/macros.el"
          "./lisp/mailalias.el"
          "./lisp/makesum.el"))
       '<)
    < src..

#      which produces:
    que produce:

#      ..src > elisp
#        (29 32 38 85 90 95 178 180 181 218 263 283 321 324 480)
#      < src..
    ..src > elisp
      (29 32 38 85 90 95 178 180 181 218 263 283 321 324 480)
    < src..

#      (Note that in this example, the first argument to @c{sort} is not
#      quoted, since the expression must be evaluated so as to produce the list
#      that is passed to @c{sort}.)
    (Nota que en este ejemplo, el primer argumento para @c{sort} no se cita,
    ya que la expresión debe ser evaluada para producir la lista que se
    pasada a @c{sort}.)

# **** Making a List of Files
*** Creando una lista de ficheros

#      The @c{recursive-lengths-list-many-files} function requires a list of
#      files as its argument. For our test examples, we constructed such a
#      list by hand; but the Emacs Lisp source directory is too large for us to
#      do for that. Instead, we will write a function to do the job for us.
#      In this function, we will use both a @c{while} loop and a recursive
#      call.
    La función @c{lista-de-longitudes-de-muchos-ficheros-recursiva} requiere una
    lista de ficheros como argumento. Para nuestros ejemplos de prueba, hemos
    construido una lista de este tipo a mano; pero el directorio fuente de Emacs
    Lisp es demasiado grande para que podamos hacerlo. En su lugar, escribiremos
    una función para hacer el trabajo por nosotros. En esta función, usaremos
    tanto un bucle @c{while} como una llamada recursiva.

#      We did not have to write a function like this for older versions of GNU
#      Emacs, since they placed all the @'{.el} files in one directory.
#      Instead, we were able to use the @c{directory-files} function, which
#      lists the names of files that match a specified pattern within a single
#      directory.
    En las viejas versiones de GNU Emacs no hacia falta escribir esta función,
    ya que todos los ficheros @'{.el} estaban colocados en un directorio. En su
    lugar, pudimos usar la función @c{directory-files}, que lista los nombres de
    los ficheros que coinciden con un patron especifico dentro de un solo
    directorio.

#      However, recent versions of Emacs place Emacs Lisp files in
#      sub-directories of the top level @f{lisp} directory. This
#      re-arrangement eases navigation. For example, all the mail related
#      files are in a @f{lisp} sub-directory called @f{mail}. But at the same
#      time, this arrangement forces us to create a file listing function that
#      descends into the sub-directories.
    Sin embargo, las versiones recientes de Emacs colocan los ficheros de Emacs
    Lisp en subdirectorios del directorio @f{lisp} de nivel superior. Esta
    reorganizacion facilita la navegación. Por ejemplo, todos los ficheros
    relacionados con el correo están en el subdirectorio @f{mail}. Pero al mismo
    tiempo, esta estructura nos obliga a crear una funcion de listado de
    ficheros que descienda dentro de los subdirectorios.

#      We can create this function, called @c{files-in-below-directory}, using
#      familiar functions such as @c{car}, @c{nthcdr}, and @c{substring} in
#      conjunction with an existing function called
#      @c{directory-files-and-attributes}. This latter function not only lists
#      all the filenames in a directory, including the names of
#      sub-directories, but also their attributes.
    Podemos crear esta función, llamada @c{ficheros-en-el-siguiente-directorio},
    usando funciones familiares como @c{car}, @c{nthcdr}, y @c{substring} en
    conjunción con una función existente llamada @c{directory-files-and-attributes}.
    Esta última función no solo listas todos los ficheros en un directorio,
    incluyendo los nombres de los subdirectorios, también sus atributos.

#      To restate our goal: to create a function that will enable us to feed
#      filenames to @c{recursive-lengths-list-many-files} as a list that looks
#      like this (but with more elements):
    Repitamos nuestro objetivo: crear una función que nos permita alimentar a
    @c{lista-de-longitudes-de-muchos-ficheros-recursiva} con nombres de fichero
    en una lista parecida a esta (pero con más elementos):

#      ..src > elisp
#        ("./lisp/macros.el"
#         "./lisp/mail/rmail.el"
#         "./lisp/makesum.el")
#      < src..
    ..src > elisp
      ("./lisp/macros.el"
       "./lisp/mail/rmail.el"
       "./lisp/makesum.el")
    < src..

#      The @c{directory-files-and-attributes} function returns a list of lists.
#      Each of the lists within the main list consists of 13 elements. The
#      first element is a string that contains the name of the file––which, in
#      GNU/Linux, may be a ‘directory file’, that is to say, a file with the
#      special attributes of a directory. The second element of the list is
#      @c{t} for a directory, a string for symbolic link (the string is the
#      name linked to), or @c{nil}.
    La función @c{directory-files-and-attributes} devuelve una lista de
    listas. Cada una de las listas de la lista principal consiste de 13
    elementos. El primer elemento es una cadena que contiene el nombre del
    fichero––que, en GNU/Linux, puede ser un ‘fichero de directorio’, es decir,
    un fichero con los atributos especiales de un directorio. El segundo
    elemento de la lista es @c{t} para un directorio, una cadena para el
    enlace simbólico (la cadena es el nombre al que enlaza), o @c{nil}.

#      For example, the first @'{.el} file in the @f{lisp/} directory is
#      @f{abbrev.el}. Its name is @f{/usr/local/share/emacs/22.1.1/lisp/abbrev.el}
#      and it is not a directory or a symbolic link.
    Por ejemplo, el primer fichero @'{.el} en el directorio @f{abbrev.el} es
    @f(abbrev.el). Su nombre es @f{/usr/local/share/emacs/22.1.1/lisp/abbrev.el}
    y no es un directorio o un enlace simbólico.

#      This is how @c{directory-files-and-attributes} lists that file and its
#      attributes:
    Asi es cómo @c{directory-files-and-attributes} lista este fichero y sus
    atributos:

#      ..src > elisp
#        ("abbrev.el"
#         nil
#         1
#         1000
#         100
#         (20615 27034 579989 697000)
#         (17905 55681 0 0)
#         (20615 26327 734791 805000)
#         13188
#         "-rw-r--r--"
#         nil
#         2971624
#         773)
#      < src..
    ..src > elisp
      ("abbrev.el"
       nil
       1
       1000
       100
       (20615 27034 579989 697000)
       (17905 55681 0 0)
       (20615 26327 734791 805000)
       13188
       "-rw-r--r--"
       nil
       2971624
       773)
    < src..

#      On the other hand, @f{mail/} is a directory within the @f{lisp/}
#      directory. The beginning of its listing looks like this:
    Por otro lado, @f{mail/} es un directorio dentro del directorio @f{lisp/}. El
    inicio del listado se ve asi:

#      ..src > elisp
#        ("mail"
#         t
#         …
#         )
#      < src..
    ..src > elisp
      ("mail"
       t
       …
       )
    < src..

#      (To learn about the different attributes, look at the documentation of
#      @c{file-attributes}. Bear in mind that the @c{file-attributes} function
#      does not list the filename, so its first element is
#      @c{directory-files-and-attributes}'s second element.)
    (Para conocer los diferentes atributos, mira en la documentación de
    @c{file-attributes}. Ten en mente que la función @c{file-attributes} no
    lista el nombre del fichero, por lo que el primer elemento es el segundo
    elemento de @c{directory-files-and-attributes}.)

#      We will want our new function, @c{files-in-below-directory}, to list the
#      @'{.el} files in the directory it is told to check, and in any
#      directories below that directory.
    Quisieramos que nuestra nueva funcion, @c{ficheros-bajo-el-dirirectorio},
    listara los ficheros @'{.el} en el directorio que le pedimos inspeccionar,
    y en cualquier directorio debajo de ese directorio.

#      This gives us a hint on how to construct @c{files-in-below-directory}:
#      within a directory, the function should add @'{.el} filenames to a list;
#      and if, within a directory, the function comes upon a sub-directory, it
#      should go into that sub-directory and repeat its actions.
    Esto nos da una pista de como construir @c{ficheros-bajo-el-dirirectorio}:
    dentro de un directorio, la función deberia añadir los ficheros @'{.el} a
    una lista; y si, dentro de un directorio, la función se encuentra con un
    subdirectorio, ir dentro de este subdirectorio y repetir sus acciones.

#      However, we should note that every directory contains a name that refers
#      to itself, called @f{.}, (“dot”) and a name that refers to its parent
#      directory, called @f{..} (“double dot”).  (In @f{/}, the root directory,
#      @f{..} refers to itself, since @f{/} has no parent.)  Clearly, we do not
#      want our @c{files-in-below-directory} function to enter those
#      directories, since they always lead us, directly or indirectly, to the
#      current directory.
    Sin embargo, debemos tener en cuenta que cada directorio contiene un nombre
    que hace referencia a sí mismo, llamado @f{.}, (“punto”) y un nombre que
    hace referencia a su directorio padre, llamado @f{..} (“doble punto”). (En
    @f{/}, el directorio raíz, @f{..} se refiere así mismo, ya que @f{/} no
    tiene padre.) Claramente, no queremos que nuestra función
    @c{ficheros-bajo-el-dirirectorio} ingrese a estos directorios, puesto que nos
    llevaran directamente o indirectamente, al directorio actual.

#      Consequently, our @c{files-in-below-directory} function must do several
#      tasks:
    Por consiguiente, nuestra función @c{ficheros-bajo-el-dirirectorio} debe realizar
    varias tareas:

#      - Check to see whether it is looking at a filename that ends in @'{.el};
#        and if so, add its name to a list.
    - Probar si se está mirando un nombre de fichero que finaliza en @'{.el} y
      si es así, añadir su nombre a una lista.

#      - Check to see whether it is looking at a filename that is the name of a
#        directory; and if so,
    - Probar si está mirando en un nombre de fichero que es el
      nombre de un directorio; y si es así,

#        - Check to see whether it is looking at @f{.}  or @f{..}; and if so
#          skip it.
      - Probar si está mirando en @f{.} o @f{..}; y si es así omitirlo.

#        - Or else, go into that directory and repeat the process.
      - Si no, ir dentro de ese directorio y repetir el proceso.


#      Let's write a function definition to do these tasks. We will use a
#      @c{while} loop to move from one filename to another within a directory,
#      checking what needs to be done; and we will use a recursive call to
#      repeat the actions on each sub-directory. The recursive pattern is
#      ‘accumulate’ (see Section @l{#Recursive Pattern: @e{accumulate}}), using
#      @c{append} as the combiner.
    Escribamos una definición de función para realizar estas tareas. Usaremos un
    bucle @c{while} para movernos de un nombre de fichero a otro con un
    directorio comprobando lo que hay que hacer; y usaremos una llamada
    recursiva para repetir las acciones en cada subdirectorio. El patrón
    recursivo es ‘accumulate’ (Consulta la Sección @l{#Patrón recursivo:
    @e{accumulate}}) usando @c{append} como combinador.

#      Here is the function:
    Aquí está la función:

#      ..src > elisp
    ..src > elisp
#        (defun files-in-below-directory (directory)
      (defun ficheros-bajo-el-dirirectorio (directorio)
#          "List the .el files in DIRECTORY and in its sub-directories."
        "Lista los ficheros .el en DIRECTORIO y en sus subdirectorios."
#          ;; Although the function will be used non-interactively,
#          ;; it will be easier to test if we make it interactive.
#          ;; The directory will have a name such as
#          ;;  "/usr/local/share/emacs/22.1.1/lisp/"
        ;; Aunque la función se utilizara no interactivamente,
        ;; será mas fácil de probar si la hacemos interactiva.
        ;; El directorio tendrá un nombre como
        ;;  "/usr/local/share/emacs/22.1.1/lisp/"
#          (interactive "DDirectory name: ")
        (interactive "DNombre del Directorio: ")
#          (let (el-files-list
#                (current-directory-list
#                 (directory-files-and-attributes directory t)))
        (let (lista-de-ficheros-el
              (lista-del-directorio-actual
               (directory-files-and-attributes directorio t)))
#            ;; while we are in the current directory
          ;; mientras estamos en el directorio actual
#            (while current-directory-list
#              (cond
          (while lista-del-directorio-actual
            (cond
#               ;; check to see whether filename ends in ‘.el’
#               ;; and if so, append its name to a list.
             ;; realiza una prueba para ver si el nombre del fichero termina
             ;; en ‘.el’ y si es así, añade su nombre a una lista.
#               ((equal ".el" (substring (car (car current-directory-list)) -3))
#                (setq el-files-list
#                      (cons (car (car current-directory-list)) el-files-list)))
             ((equal ".el" (substring (car (car lista-del-directorio-actual)) -3))
              (setq lista-de-ficheros-el
                    (cons (car (car lista-del-directorio-actual)) lista-de-ficheros-el)))
#               ;; check whether filename is that of a directory
             ;; prueba si el nombre del fichero es un directorio
#               ((eq t (car (cdr (car current-directory-list))))
             ((eq t (car (cdr (car lista-del-directorio-actual))))
#                ;; decide whether to skip or recurse
              ;; decide si ignorarlo o hacer recursión
#                (if
#                    (equal "."
#                           (substring (car (car current-directory-list)) -1))
              (if
                  (equal "."
                         (substring (car (car lista-del-directorio-actual)) -1))
#                    ;; then do nothing since filename is that of
#                    ;;   current directory or parent, "." or ".."
                  ;; entonces no hacer nada puesto que el nombre del fichero es
                  ;; el directorio actual o el padre, "." o ".."
#                    ()
                  ()
#                  ;; else descend into the directory and repeat the process
                ;; de otra forma, desciende dentro del directorio y repite el proceso
#                  (setq el-files-list
#                        (append
#                         (files-in-below-directory
#                          (car (car current-directory-list)))
#                         el-files-list)))))
                (setq lista-de-ficheros-el
                      (append
                       (ficheros-bajo-el-dirirectorio
                        (car (car lista-del-directorio-actual)))
                       lista-de-ficheros-el)))))
#              ;; move to the next filename in the list; this also
#              ;; shortens the list so the while loop eventually comes to an end
            ;; moverse al siguiente fichero en la lista; esto también acorta
            ;; la lista para que el bucle while eventualmente llegue a su fin
#              (setq current-directory-list (cdr current-directory-list)))
            (setq lista-del-directorio-actual (cdr lista-del-directorio-actual)))
#            ;; return the filenames
          ;; devuelve los ficheros
#            el-files-list))
          lista-de-ficheros-el))
#      < src..
    < src..

#      The @c{files-in-below-directory} function takes one argument, the name of
#      a directory.
    La funcion @c{ficheros-bajo-el-dirirectorio} toma un argumento, el nombre de
    un directorio.

#      Thus, on my system,
    Por eso, en mi sistema,

#      ..src > elisp
#        (length
#         (files-in-below-directory "/usr/local/share/emacs/22.1.1/lisp/"))
#      < src..
    ..src > elisp
      (length
       (ficheros-bajo-el-dirirectorio "/usr/local/share/emacs/22.1.1/lisp/"))
    < src..

#     tells me that in and below my Lisp sources directory are 1031 @'f(.el) files.
    me dice que en y debajo de mi directorio de codigo fuente Lisp hay 1031
    ficheros @'f{.el}

#     @c(files-in-below-directory) returns a list in reverse alphabetical order.
#     An expression to sort the list in alphabetical order looks like this
    @c{ficheros-bajo-el-dirirectorio} devuelve una lista en orden alfabético
    inverso. Una expresión para ordenar la lista en orden alfabetico tiene el
    siguiente aspecto:

#      ..src > elisp
#        (sort
#         (files-in-below-directory "/usr/local/share/emacs/22.1.1/lisp/")
#         'string-lessp)
#      < src..
    ..src > elisp
      (sort
       (ficheros-bajo-el-dirirectorio "/usr/local/share/emacs/22.1.1/lisp/")
       'string-lessp)
    < src..

# **** Counting function definitions
*** Contando definiciones de función

#      Our immediate goal is to generate a list that tells us how many function
#      definitions contain fewer than 10 words and symbols, how many contain
#      between 10 and 19 words and symbols, how many contain between 20 and 29
#      words and symbols, and so on.
    Nuestro objetivo inmediato es generar una lista que nos diga cuantas
    definiciones de funcion contienen menos de 10 palabras y símbolos, cuantas
    contienen entre 10 y 19 palabras y símbolos, cuantas entre 20 y 29, y así
    sucesivamente.

#      With a sorted list of numbers, this is easy: count how many elements of
#      the list are smaller than 10, then, after moving past the numbers just
#      counted, count how many are smaller than 20, then, after moving past the
#      numbers just counted, count how many are smaller than 30, and so on.
#      Each of the numbers, 10, 20, 30, 40, and the like, is one larger than
#      the top of that range. We can call the list of such numbers the
#      @c{top-of-ranges} list.
    Con una lista ordenada de números, esto es fácil: se cuentan cuantos
    elementos de la lista son más pequeños de 10, luego, despues de haber pasado
    los numeros que se acaban de contar, se cuenta cuantos son más pequeños de
    20, despues de haber pasado los numeros que se acaban de contar, los que son
    más pequeños de 30, y así sucesivamente. Cada uno de los números, 10, 20,
    30, 40, y similares, es uno más grande que la parte superior de ese
    rango. Podemos llamar a esta lista de estos numeros, @c{cima-de-rangos}.

#      If we wished, we could generate this list automatically, but it is
#      simpler to write a list manually. Here it is:
    Si quisieramos, podriamos generar esta lista automáticamente, pero es más
    sencillo escribir una lista manualmente. Aquí está:

#      ..src > elisp
#        (defvar top-of-ranges
#         '(10  20  30  40  50
#           60  70  80  90 100
#          110 120 130 140 150
#          160 170 180 190 200
#          210 220 230 240 250
#          260 270 280 290 300)
#         "List specifying ranges for ‘defuns-per-range’.")
#      < src..
    ..src > elisp
      (defvar cima-de-rangos
       '(10  20  30  40  50
         60  70  80  90 100
        110 120 130 140 150
        160 170 180 190 200
        210 220 230 240 250
        260 270 280 290 300)
       "Listar especificando rangos para ‘definiciones-por-rango’.")
    < src..

#      To change the ranges, we edit this list.
    Para cambiar los rangos, editamos esta lista.

#      Next, we need to write the function that creates the list of the number
#      of definitions within each range. Clearly, this function must take the
#      @c{sorted-lengths} and the @c{top-of-ranges} lists as arguments.
    A continuacion, necesitamos escribir la función que crea la lista del número
    de definiciones dentro de cada rango. Evidentemente, esta función debe tomar las
    listas @c{longitudes-ordenadas} y @c{cima-de-rangos} como argumentos.

#      The @c{defuns-per-range} function must do two things again and again: it
#      must count the number of definitions within a range specified by the
#      current top-of-range value; and it must shift to the next higher value
#      in the @c{top-of-ranges} list after counting the number of definitions
#      in the current range. Since each of these actions is repetitive, we can
#      use @c{while} loops for the job. One loop counts the number of
#      definitions in the range defined by the current top-of-range value, and
#      the other loop selects each of the top-of-range values in turn.
    La función @c{definiciones-por-rango} debe hacer dos cosas una y otra vez:
    debe contar el número de definiciones con un rango específicado por el valor
    superior actual del rango; y debe pasar al siguiente valor superior en la
    lista @c{cima-de-rangos} después de contar el número de definiciones en el
    rango actual. Dado que cada una de estas acciones es repetitiva, se pueden
    utilizar bucles @c{while} para el trabajo. Un bucle cuenta el número de
    definiciones en el rango definido por el valor superior actual, y el otro
    bucle a su vez selecciona cada uno de los valores superiores del rango.

#      Several entries of the @c{sorted-lengths} list are counted for each
#      range; this means that the loop for the @c{sorted-lengths} list will be
#      inside the loop for the @c{top-of-ranges} list, like a small gear inside
#      a big gear.
    Se cuentan varias entradas de la lista de @c{longitudes-ordenadas} para cada
    rango; esto significa que el bucle para la lista de @c{longitudes-ordenadas}
    estara dentro del bucle para la lista de @c{cima-de-rangos}, como un pequeño
    engrane dentro de un gran mecanismo.

#      The inner loop counts the number of definitions within the range. It is
#      a simple counting loop of the type we have seen before.  (See Section
#      @l{#A loop with an incrementing counter}.)  The true-or-false test of the
#      loop tests whether the value from the @c{sorted-lengths} list is smaller
#      than the current value of the top of the range. If it is, the function
#      increments the counter and tests the next value from the
#      @c{sorted-lengths} list.
    El bucle interno cuenta el número de definiciones dentro del rango. Es un
    simple bucle de conteo del tipo que hemos visto antes. (Ver la Seccion @l{#Un
    bucle con un contador incremental}). La prueba verdadero-o-falso del bucle
    comprueba si el valor de la lista @c{longitudes-ordenadas} es menor que el
    valor actual de la cima del rango. Si es así, la función incrementa el
    contador y prueba el siguiente valor de la lista @c{longitudes-ordenadas}.

#      The inner loop looks like this:
    El bucle interno se ve asi:

#      ..src > elisp
#        (while length-element-smaller-than-top-of-range
#          (setq number-within-range (1+ number-within-range))
#          (setq sorted-lengths (cdr sorted-lengths)))
#      < src..
    ..src > elisp
      (while elemento-de-longitud-menor-que-el-de-la-cima-de-rango
        (setq numero-dentro-del-rango (1+ numero-dentro-del-rango))
        (setq longitudes-ordenadas (cdr longitudes-ordenadas)))
    < src..

#     The outer loop must start with the lowest value of the @c(top-of-ranges)
#     list, and then be set to each of the succeeding higher values in
#     turn. This can be done with a loop like this:
    El bucle exterior debe empezar con el valor más bajo de la lista
    @c{cima-de-rangos} y, a continuacion, ajustarse a cada uno de los valores
    superiores sucesivos. Esto puede ser hecho con un bucle como
    este:

#      ..src > elisp
#        (while top-of-ranges
#          body-of-loop…
#          (setq top-of-ranges (cdr top-of-ranges)))
#      < src..
    ..src > elisp
      (while cima-de-rangos
        cuerpo-del-bucle…
        (setq cima-de-rangos (cdr cima-de-rangos)))
    < src..

#      Put together, the two loops look like this:
    Puestos juntos, los dos bucles se ven asi:

#      ..src > elisp
    ..src > elisp
#        (while top-of-ranges
      (while cima-de-rangos

#          ;; Count the number of elements within the current range.
        ;; Cuenta el número de elementos dentro del rango actual.
#          (while length-element-smaller-than-top-of-range
#            (setq number-within-range (1+ number-within-range))
#            (setq sorted-lengths (cdr sorted-lengths)))
        (while elemento-de-longitud-menor-que-el-de-la-cima-de-rango
          (setq numero-dentro-del-rango (1+ numero-dentro-del-rango))
          (setq longitudes-ordenadas (cdr longitudes-ordenadas)))

#          ;; Move to next range.
        ;; Mover al siguiente rango.
#          (setq top-of-ranges (cdr top-of-ranges)))
        (setq cima-de-rangos (cdr cima-de-rangos)))
#      < src..
    < src..

#      In addition, in each circuit of the outer loop, Emacs should record the
#      number of definitions within that range (the value of
#      @c{number-within-range}) in a list. We can use @c{cons} for this
#      purpose.  (See Section @l{#@c{cons}}.)
    Además, en cada iteracion del bucle exterior, Emacs debe registrar el número de
    definiciones dentro de ese rango (el valor de @c{numero-dentro-del-rango}) en una
    lista. Podemos usar @c{cons} para este propósito. (Consulta la Seccion
    @l{#@c{cons}}.)

#      The @c{cons} function works fine, except that the list it constructs
#      will contain the number of definitions for the highest range at its
#      beginning and the number of definitions for the lowest range at its end.
#      This is because @c{cons} attaches new elements of the list to the
#      beginning of the list, and since the two loops are working their way
#      through the lengths' list from the lower end first, the
#      @c{defuns-per-range-list} will end up largest number first. But we will
#      want to print our graph with smallest values first and the larger later.
#      The solution is to reverse the order of the @c{defuns-per-range-list}.
#      We can do this using the @c{nreverse} function, which reverses the order
#      of a list.
    La función @c{cons} trabaja bien, excepto que la lista que construye
    contendrá el número de definiciones para el rango mas alto y el número de
    definiciones para el rango más bajo al final. Esto se debe a que @c{cons}
    adjunta nuevos elementos de la lista al principio de la lista, y ya que los
    dos bucles hacen cálculos a través de la lista de longitudes iniciando desde el
    extremo inferior, la @c{lista-de-definiciones-por-rango}
    terminara con el numero mayor al pricipio. Pero querremos imprimir nuestro
    grafo con los valores pequeños primero y los más grandes después. La
    solución es invertir el orden de la @c{lista-de-definiciones-por-rango}.
    Podemos hacer esto usando la función @c{nreverse}, que invierte el orden de
    una lista.

#      For example,
    Por ejemplo,

#      ..src > elisp
#        (nreverse '(1 2 3 4))
#      < src..
    ..src > elisp
      (nreverse '(1 2 3 4))
    < src..

#      produces:
    produce:

#      ..src > elisp
#        (4 3 2 1)
#      < src..
    ..src > elisp
      (4 3 2 1)
    < src..

#      Note that the @c{nreverse} function is “destructive”––that is, it
#      changes the list to which it is applied; this contrasts with the @c{car}
#      and @c{cdr} functions, which are non-destructive. In this case, we do
#      not want the original @c{defuns-per-range-list}, so it does not matter
#      that it is destroyed.  (The @c{reverse} function provides a reversed
#      copy of a list, leaving the original list as is.)
    Advertir que la función @c{nreverse} es “destructiva”––es decir, cambia la
    lista a la que se aplica; esto contrasta con las funciones @c{car} y
    @c{cdr}, que no son destructivas. En este caso, no queremos la
    @c{lista-de-definiciones-por-rango} original, asi que no importa que sea
    destruida. (La función @c{reverse} proporciona un copia inversa de una lista,
    dejando la lista original tal cual.)

#      Put all together, the @c{defuns-per-range} looks like this:
    En conjunto, la funcion @c{definiciones-por-rango} luce asi:

#      ..src > elisp
    ..src > elisp
#        (defun defuns-per-range (sorted-lengths top-of-ranges)
      (defun definiciones-por-rango (longitudes-ordenadas cima-de-rangos)
#          "SORTED-LENGTHS defuns in each TOP-OF-RANGES range."
        "LONGITUDES-ORDENADAS de defuns en cada CIMA-DE-RANGOS."
#          (let ((top-of-range (car top-of-ranges))
#                (number-within-range 0)
#                defuns-per-range-list)
        (let ((cima-de-rango (car cima-de-rangos))
              (numero-dentro-del-rango 0)
              lista-de-definiciones-por-rango)

#            ;; Outer loop.
          ;; Bucle Externo.
#            (while top-of-ranges
          (while cima-de-rangos

#              ;; Inner loop.
            ;; Bucle Interno.
#              (while (and
            (while (and
#                      ;; Need number for numeric test.
                    ;; Necesita el número para la prueba numérica.
#                      (car sorted-lengths)
#                      (< (car sorted-lengths) top-of-range))
                    (car longitudes-ordenadas)
                    (< (car longitudes-ordenadas) cima-de-rango))

#                ;; Count number of definitions within current range.
              ;; Cuenta el número de definiciones dentro del rango actual.
#                (setq number-within-range (1+ number-within-range))
#                (setq sorted-lengths (cdr sorted-lengths)))
              (setq numero-dentro-del-rango (1+ numero-dentro-del-rango))
              (setq longitudes-ordenadas (cdr longitudes-ordenadas)))

#              ;; Exit inner loop but remain within outer loop.
            ;; Sale del bucle interno pero permanece dentro del bucle externo.

#              (setq defuns-per-range-list
#                    (cons number-within-range defuns-per-range-list))
#              (setq number-within-range 0)      ; Reset count to zero.
            (setq lista-de-definiciones-por-rango
                  (cons numero-dentro-del-rango lista-de-definiciones-por-rango))
            (setq numero-dentro-del-rango 0)      ; Restablece el conteo a cero.

#              ;; Move to next range.
            ;; Mover al siguiente rango.
#              (setq top-of-ranges (cdr top-of-ranges))
            (setq cima-de-rangos (cdr cima-de-rangos))
#              ;; Specify next top of range value.
            ;; Designa el siguiente valor superior del rango.
#              (setq top-of-range (car top-of-ranges)))
            (setq cima-de-rango (car cima-de-rangos)))
#
#            ;; Exit outer loop and count the number of defuns larger than
#            ;;   the largest top-of-range value.
          ;; Sale del bucle externo y cuenta el número de defuns mayor que
          ;; el valor mas alto de cima-de-rango.
#            (setq defuns-per-range-list
#                  (cons
#                   (length sorted-lengths)
#                   defuns-per-range-list))
          (setq lista-de-definiciones-por-rango
                (cons
                 (length longitudes-ordenadas)
                 lista-de-definiciones-por-rango))

#            ;; Return a list of the number of definitions within each range,
#            ;;   smallest to largest.
          ;; Devuelve una lista del número de definiciones dentro de cada rango,
          ;;   del menor al mayor.
#            (nreverse defuns-per-range-list)))
          (nreverse lista-de-definiciones-por-rango)))
#      < src..
    < src..

#      The function is straightforward except for one subtle feature. The
#      true-or-false test of the inner loop looks like this:
    La función es sencilla, excepto por una caracteristica sutil. La prueba
    verdadero-o-falso del bucle interno es asi:

#      ..src > elisp
#        (and (car sorted-lengths)
#             (< (car sorted-lengths) top-of-range))
#      < src..
    ..src > elisp
      (and (car longitudes-ordenadas)
           (< (car longitudes-ordenadas) cima-de-rango))
    < src..

#      instead of like this:
    en lugar de asi:

#      ..src > elisp
#        (< (car sorted-lengths) top-of-range)
#      < src..
    ..src > elisp
      (< (car longitudes-ordenadas) cima-de-rango)
    < src..

#      The purpose of the test is to determine whether the first item in the
#      @c{sorted-lengths} list is less than the value of the top of the range.
    El propósito de la prueba es determinar si el primer elemento de la lista
    de @c{longitudes-ordenadas} es inferior al valor de la parte superior del rango.

#      The simple version of the test works fine unless the @c{sorted-lengths}
#      list has a @c{nil} value. In that case, the @c{(car sorted-lengths)}
#      expression function returns @c{nil}. The @c{<} function cannot compare
#      a number to @c{nil}, which is an empty list, so Emacs signals an error
#      and stops the function from attempting to continue to execute.
    La versión simple de la prueba funciona bien a menos que la lista
    @c{longitudes-ordenadas} tenga un valor @c{nil}. En este caso, la expresión
    @c{(car longitudes-ordenadas)} devuelve @c{nil}. La función @c{<} no puede
    compara un número con @c{nil}, que es una lista vacía, por lo que Emacs indica un
    error e impide que la función siga ejecutandose.

#      The @c{sorted-lengths} list always becomes @c{nil} when the counter
#      reaches the end of the list. This means that any attempt to use the
#      @c{defuns-per-range} function with the simple version of the test will
#      fail.
    La lista de @c{longitudes-ordenadas} siempre se convierte en @c{nil} cuando el
    contador llega al fin de la lista. Esto significa que cualquier intento
    de usar la función @c{definiciones-por-rango} con la versión simple de la prueba
    fallará.

#      We solve the problem by using the @c{(car sorted-lengths)} expression in
#      conjunction with the @c{and} expression. The @c{(car sorted-lengths)}
#      expression returns a non-@c{nil} value so long as the list has at least
#      one number within it, but returns @c{nil} if the list is empty. The
#      @c{and} expression first evaluates the @c{(car sorted-lengths)}
#      expression, and if it is @c{nil}, returns false @e{without} evaluating
#      the @c{<} expression. But if the @c{(car sorted-lengths)} expression
#      returns a non-@c{nil} value, the @c{and} expression evaluates the @c{<}
#      expression, and returns that value as the value of the @c{and}
#      expression.
    Resolvemos el problema usando la expresion @c{(car longitudes-ordenadas)}
    junto con la expresión @c{and}. La expresión @c{(car longitudes-ordenadas)}
    devuelve un valor no @c{nil} siempre y cuando la lista contenga al menos un
    número, pero devuelve @c{nil} si la lista está vacía. La expresión @c{and}
    primero evalúa @c{(car longitudes-ordenadas)}, y si es @c{nil}, devuelve
    falso @e{sin} evaluar la expresión @c{<} y devuelve este valor como el valor
    de la expresión @c{and}.

#      This way, we avoid an error.  (See Section @l{#The @c{kill-new}
#      function}, for information about @c{and}.)
    De esta manera, evitamos un error.  (Para mas información sobre @c{and},
    consulta la Seccion @l{#La función @c{kill-new}}

#      Here is a short test of the @c{defuns-per-range} function. First,
#      evaluate the expression that binds (a shortened) @c{top-of-ranges} list
#      to the list of values, then evaluate the expression for binding the
#      @c{sorted-lengths} list, and then evaluate the @c{defuns-per-range}
#      function.
    He aqui una breve prueba de la función @c{definiciones-por-rango}. Primero,
    evalúa la expresión que enlaza la lista (ordenada) @c{cima-de-rangos} a
    la lista de valores, luego evalúa la expresión que enlaza la lista
    @c{longitudes-ordenadas}, y despues evalúa la función @c{definiciones-por-rango}.

#      ..src > elisp
    ..src > elisp
#        ;; (Shorter list than we will use later.)
      ;; (La lista ordenada que usaremos después.)
#        (setq top-of-ranges
#         '(110 120 130 140 150
#           160 170 180 190 200))
      (setq cima-de-rangos
       '(110 120 130 140 150
         160 170 180 190 200))

#        (setq sorted-lengths
#              '(85 86 110 116 122 129 154 176 179 200 265 300 300))
      (setq longitudes-ordenadas
            '(85 86 110 116 122 129 154 176 179 200 265 300 300))

#        (defuns-per-range sorted-lengths top-of-ranges)
      (definiciones-por-rango longitudes-ordenadas cima-de-rangos)
#      < src..
    < src..

#      The list returned looks like this:
    Esta es la lista que devuelve:

#      ..src > elisp
#        (2 2 2 0 0 1 0 2 0 0 4)
#      < src..
    ..src > elisp
      (2 2 2 0 0 1 0 2 0 0 4)
    < src..

#      Indeed, there are two elements of the @c{sorted-lengths} list smaller
#      than 110, two elements between 110 and 119, two elements between 120 and
#      129, and so on. There are four elements with a value of 200 or larger.
    De hecho, hay dos elementos de la lista @c{longitudes-ordenadas} menores a 110,
    dos elementos entre 110 y 119, dos elementos entre 120 y 129, etcetera. Hay
    cuatro elementos con un valor de 200 o superior.

# * Readying a Graph
* Preparar un grafico

#   Our goal is to construct a graph showing the numbers of function
#   definitions of various lengths in the Emacs lisp sources.
  Nuestro objetivo es construir un grafo que muestre el numero de definiciones
  de función de varios tamaños en el codigo fuente de Emacs lisp.

#   As a practical matter, if you were creating a graph, you would probably use
#   a program such as @${gnuplot} to do the job.  (@${gnuplot} is nicely
#   integrated into GNU Emacs.)  In this case, however, we create one from
#   scratch, and in the process we will re-acquaint ourselves with some of what
#   we learned before and learn more.
  Como cuestion práctica, si estuvieras creando un grafico, probablemente
  usarías un programa como @${gnuplot} para hacer el trabajo. (@${gnuplot} está
  bien integrado dentro de GNU Emacs.) En este caso, sin embargo, creamos uno
  desde cero, y en el proceso volveremos a familiarizarnos con algo de lo
  que aprendimos antes y aprenderemos más.

#   In this chapter, we will first write a simple graph printing function.
#   This first definition will be a @:{prototype}, a rapidly written function
#   that enables us to reconnoiter this unknown graph-making territory. We
#   will discover dragons, or find that they are myth. After scouting the
#   terrain, we will feel more confident and enhance the function to label the
#   axes automatically.
  En este capítulo, primero escribiremos una simple funcion de impresion de
  graficos. Esta primera definición será un @:{prototipo}, una función escrita
  rápidamente que nos permita reconocer este territorio desconocido en la
  creacion de graficos. Descubriremos dragones, o descubriremos que son
  mitos. Después de explorar el terreno, nos sentiremos más seguros y
  mejoraremos la función para etiquetar las coordenadas automáticamente.

#   Since Emacs is designed to be flexible and work with all kinds of
#   terminals, including character-only terminals, the graph will need to be
#   made from one of the ‘typewriter’ symbols. An asterisk will do; as we
#   enhance the graph-printing function, we can make the choice of symbol a
#   user option.
  Dado que Emacs está diseñado para ser flexible y funcionar con todo tipo de
  terminales, incluyendo los terminales de solo caracteres, el grafico debera
  realizarse a partir de uno de los simbolos de ‘maquina de escribir’. Un asterisco
  servira; a medida que mejoremos la función de impresión del grafico, podremos
  hacer que el simbolo a usar sea una elección del usuario.

#   We can call this function @c{graph-body-print}; it will take a
#   @c{numbers-list} as its only argument. At this stage, we will not label
#   the graph, but only print its body.
  Podemos llamar a esta función @c{imprimir-cuerpo-grafico}; tomará como unico
  argumento una @c{lista-de-numeros}. En esta etapa, no etiquetaremos el grafico,
  sino que solo imprimiremos su cuerpo.

#   The @c{graph-body-print} function inserts a vertical column of asterisks
#   for each element in the @c{numbers-list}. The height of each line is
#   determined by the value of that element of the @c{numbers-list}.
  La función @c{imprimir-cuerpo-grafico} inserta una columna vertical de asteriscos
  para cada elemento en la @c{lista-de-numeros}. La altura de cada línea
  está determinada por el valor de ese elemento de la @c{lista-de-numeros}.

#   Inserting columns is a repetitive act; that means that this function can be
#   written either with a @c{while} loop or recursively.
  Insertar columnas es un acto repetitivo; esto significa que esta función
  puede escribirse con un bucle @c{while} o recursivamente.

#   Our first challenge is to discover how to print a column of asterisks.
#   Usually, in Emacs, we print characters onto a screen horizontally, line by
#   line, by typing. We have two routes we can follow: write our own
#   column-insertion function or discover whether one exists in Emacs.
  Nuestro primer reto es descubrir como imprimir una columna de
  asteriscos. Normalmente, en Emacs, se imprimen caracteres dentro de una
  pantalla horizontalmente, escribiendo línea a línea. Tenemos dos rutas
  a seguir: escribir nuestra propia función de insercion-de-columnas o descubrir
  si ya existe una en Emacs.

#   To see whether there is one in Emacs, we can use the @k{M-x apropos}
#   command. This command is like the @k{C-h a} @%c(command-apropos) command,
#   except that the latter finds only those functions that are commands. The
#   @k{M-x apropos} command lists all symbols that match a regular expression,
#   including functions that are not interactive.
  Para ver si hay una en Emacs, podemos usar el comando @k{M-x apropos}. Este
  comando es como el comando @k{C-h a} @%c(command-apropos), excepto que este
  último solo encuentra aquellas funciones que son comandos. El comando @k{M-x
  apropos} lista todos los símbolos que coinciden con una expresión regular,
  incluyendo funciones que no son interactivas.

#   What we want to look for is some command that prints or inserts columns.
#   Very likely, the name of the function will contain either the word ‘print’
#   or the word ‘insert’ or the word ‘column’. Therefore, we can simply type
#   @k{M-x apropos RET print\|insert\|column RET} and look at the result. On
#   my system, this command once too takes quite some time, and then produced a
#   list of 79 functions and variables. Now it does not take much time at all
#   and produces a list of 211 functions and variables. Scanning down the
#   list, the only function that looks as if it might do the job is
#   @c{insert-rectangle}.
  Lo que queremos buscar es algún comando que imprima o inserte columnas. Muy
  probablemente, el nombre de la función contendrá la palabra ‘print’ o la
  palabra ‘insert’ o la palabra ‘column’. Por esta razón, podemos simplemente
  escribir @k{M-x apropos RET print\|insert\|column RET} y ver el resultado. En
  mi sistema, este comando demoro bastante tiempo, y luego produjo una
  lista de 79 funciones y variables. Ahora no demora mucho y produce una
  lista de 211 funciones y variables. Explorando la lista, la única función que
  parece puede hacer el trabajo es @c{insert-rectangle}.

#   Indeed, this is the function we want; its documentation says:
  De hecho, esta es la función que queremos; su documentación dice:

#   ..example >
#     insert-rectangle:
#     Insert text of RECTANGLE with upper left corner at point.
#     RECTANGLE's first line is inserted at point,
#     its second line is inserted at a point vertically under point, etc.
#     RECTANGLE should be a list of strings.
#     After this command, the mark is at the upper left corner
#     and point is at the lower right corner.
#   < example..
  ..example >
    insert-rectangle:
    Insertar texto de RECTANGLE con la esquina superior izquierda en el punto
    La primera línea de RECTANGLE se inserta en el punto
    la segunda línea se inserta en un punto verticalmente debajo del punto, etc
    RECTANGLE debe ser una lista de cadenas.
    Después de este comando, la marca está en la esquina izquierda
    superior y el punto en la esquina inferior derecha.
  < example..

#   We can run a quick test, to make sure it does what we expect of it.
  Podemos ejecutar una prueba rápida, para asegurarnos de que hace lo que esperamos.

#   Here is the result of placing the cursor after the @c{insert-rectangle}
#   expression and typing @k{C-u C-x C-e} @%c(eval-last-sexp). The function
#   inserts the strings @c{"first"}, @c{"second"}, and @c{"third"} at and below
#   point. Also the function returns @c{nil}.
  Este es el resultado de colocar el cursor después de la expresión
  @c{insert-rectangle} y presionar @k{C-u C-x C-e} @%c(eval-last-sexp). La
  función inserta las cadenas @c{"primero"}, @c{"segundo"}, y @c{"tercero"}
  debajo del punto. También la función devuelve @c{nil}.

#   ..example >
#     (insert-rectangle '("first" "second" "third"))first
#                                                   second
#                                                   thirdnil
#   < example..
  ..example >
    (insert-rectangle '("primero" "segundo" "tercero"))primero
                                                       segundo
                                                       terceronil
  < example..

#   Of course, we won't be inserting the text of the @c{insert-rectangle}
#   expression itself into the buffer in which we are making the graph, but
#   will call the function from our program. We shall, however, have to make
#   sure that point is in the buffer at the place where the
#   @c{insert-rectangle} function will insert its column of strings.
  Por supuesto, no insertaremos el texto de la expresión @c{insert-rectangle} en
  el búfer en el que estamos haciendo el grafico, sino qque llamaremos a la
  función desde nuestro programa. Sin embargo, tendremos que asegurarnos de que
  el punto está en el búfer en el lugar donde la función
  @c{insert-rectangle} insertará la columna de cadenas.

#   If you are reading this in Info, you can see how this works by switching to
#   another buffer, such as the @f{*scratch*} buffer, placing point somewhere
#   in the buffer, typing @k{M-:}, typing the @c{insert-rectangle} expression
#   into the minibuffer at the prompt, and then typing @k{RET}. This causes
#   Emacs to evaluate the expression in the minibuffer, but to use as the value
#   of point the position of point in the @f{*scratch*} buffer.  (@k{M-:} is
#   the keybinding for @c{eval-expression}. Also, @c{nil} does not appear in
#   the @f{*scratch*} buffer since the expression is evaluated in the
#   minibuffer.)
  Si estás leyendo esto en Emacs, puedes ver como funciona cambiando a otro
  búfer, como el búfer @f{*scratch*}, colocar el punto a algún lugar del búfer,
  presionar @k{M-:}, despues escribir la expresión @c{insert-rectangle} dentro
  del minibúfer en la consola, y presionar @k{RET}. Esto hace que Emacs evalúe
  la expresión en el minibúfer, pero utilice como el valor del punto la posición
  del punto en el búfer @f{*scratch*}. (@k{M-:} es el atajo para
  @c{eval-expression}. Tampoco aparece @c{nil} en el búfer @f{*scratch*}, ya que
  la expresión se evalúa en el minibúfer.)

#   We find when we do this that point ends up at the end of the last inserted
#   line––that is to say, this function moves point as a side-effect. If we
#   were to repeat the command, with point at this position, the next insertion
#   would be below and to the right of the previous insertion. We don't want
#   this!  If we are going to make a bar graph, the columns need to be beside
#   each other.
  Cuando hacemos esto, encontraremos que el punto termina al final de la
  última línea insertada––es decir, esta función mueve el punto como un
  efecto secundario. Si repitieramos el comando, con el punto en esta
  posición, la siguiente inserción estaria debajo y a la derecha de la
  inserción anterior. ¡No queremos esto!. Si vamos a crear un
  gráfico de barras, las columnas deben estar una al lado de la otra.

#   So we discover that each cycle of the column-inserting @c{while} loop must
#   reposition point to the place we want it, and that place will be at the
#   top, not the bottom, of the column. Moreover, we remember that when we
#   print a graph, we do not expect all the columns to be the same height.
#   This means that the top of each column may be at a different height from
#   the previous one. We cannot simply reposition point to the same line each
#   time, but moved over to the right––or perhaps we can…
  Así descubrimos que cada ciclo de insercion de columnas del bucle @c{while}
  debe reposicionar el punto al lugar que queremos, y ese lugar estará en la
  parte superior, no en la inferior de la columna. Ademas, recordamos que cuando
  imprimimos un grafico, no se espera que todas las columnas tengan la misma
  altura. Esto significa que la parte superior de cada columna puede estar a una
  altura diferente de la anterior. No podemos simplemente reposicionar el punto
  en la misma línea cada vez, sino movernos hacia la derecha––o tal vez podamos…

#   We are planning to make the columns of the bar graph out of asterisks. The
#   number of asterisks in the column is the number specified by the current
#   element of the @c{numbers-list}. We need to construct a list of asterisks
#   of the right length for each call to @c{insert-rectangle}. If this list
#   consists solely of the requisite number of asterisks, then we will have
#   position point the right number of lines above the base for the graph to
#   print correctly. This could be difficult.
  Estamos planeando crear las columnas del grafico de barras con asteriscos. El
  número de asteriscos en la columna es el número específicado por el elemento
  actual de la @c{lista-de-numeros}. Necesitamos construir una lista de asteriscos
  de la longitud correcta para cada llamada a @c{insert-rectangle}. Si esta lista
  consiste únicamente del número requerido de asteriscos, entonces tendremos
  la posición de punto el número correcto de líneas sobre la base del gráfico
  para imprimirse correctamente. Esto podría ser difícil.

#   Alternatively, if we can figure out some way to pass @c{insert-rectangle} a
#   list of the same length each time, then we can place point on the same line
#   each time, but move it over one column to the right for each new column.
#   If we do this, however, some of the entries in the list passed to
#   @c{insert-rectangle} must be blanks rather than asterisks. For example, if
#   the maximum height of the graph is 5, but the height of the column is 3,
#   then @c{insert-rectangle} requires an argument that looks like this:
  Alternativamente, si podemos encotrar alguna manear de pasar a
  @c{insert-rectangle} una lista de la misma longitud cada vez, entonces podemos
  posicionar el punto en la misma línea cada vez, pero moverlo una
  columna a la derecha para cada nueva columna. Si hacemos esto, sin embargo,
  algunas de las entradas en la lista pasaba a @c{insert-rectangle} deben ser
  espacios en blanco en vez de asteriscos. Por ejemplo, si la altura máxima del
  grafico es 5, pero la altura de la columna es 3, entonces @c{insert-rectangle}
  requiere un argumento como este:

#   ..src > elisp
#     (" " " " "*" "*" "*")
#   < src..
  ..src > elisp
    (" " " " "*" "*" "*")
  < src..

#   This last proposal is not so difficult, so long as we can determine the
#   column height. There are two ways for us to specify the column height: we
#   can arbitrarily state what it will be, which would work fine for graphs of
#   that height; or we can search through the list of numbers and use the
#   maximum height of the list as the maximum height of the graph. If the
#   latter operation were difficult, then the former procedure would be
#   easiest, but there is a function built into Emacs that determines the
#   maximum of its arguments. We can use that function. The function is
#   called @c{max} and it returns the largest of all its arguments, which must
#   be numbers. Thus, for example,
  Esta última propuesta no es tan difícil, siempre y cuando podamos determinar
  la altura de la columna. Hay dos maneras de especificar la altura de la
  columna: podemos indicar arbitrariamente cual sera, lo que funcionaría bien
  para gráficos de esa altura; o podemos buscar a través de la lista de números
  y usar la altura máxima de la lista como la altura máxima del grafico. Si la
  segunda operación fuera difícil, entonces el procedimiento anterior seria mas fácil,
  pero hay una función nativa en Emacs para determinar el máximo de sus
  argumentos. Podemos usar esta función. La función se llama @c{max} y
  devuelve el mayor de todos sus argumentos, que deben ser números. Asi, por
  ejemplo,

#   ..src > elisp
#     (max  3 4 6 5 7 3)
#   < src..
  ..src > elisp
    (max  3 4 6 5 7 3)
  < src..

#   returns 7.  (A corresponding function called @c{min} returns the smallest
#   of all its arguments.)
  devuelve 7. (Una función correspondiente llamada @c{min} devuelve el más
  pequeño de todos sus argumentos.)

#   However, we cannot simply call @c{max} on the @c{numbers-list}; the @c{max}
#   function expects numbers as its argument, not a list of numbers. Thus, the
#   following expression,
  Sin embargo, no podemos simplemente llamar a @c{max} sobre la @c{lista-de-numeros};
  la función @c{max} espera números como su argumento, no una lista de
  números. De este modo, la siguiente expresión,

#   ..src > elisp
#     (max '(3 4 6 5 7 3))
#   < src..
  ..src > elisp
    (max '(3 4 6 5 7 3))
  < src..

#   produces the following error message:
  produce el siguiente mensaje error:

#   ..example >
#     Wrong type of argument:  number-or-marker-p, (3 4 6 5 7 3)
#   < example..
  ..example >
    Tipo incorrecto de argumento: number-or-marker-p, (3 4 6 5 7 3)
  < example..

#   We need a function that passes a list of arguments to a function. This
#   function is @c{apply}. This function ‘applies’ its first argument (a
#   function) to its remaining arguments, the last of which may be a list.
  Necesitamos una función que pase una lista de argumentos a una
  función. Esa función es @c{apply}. Esta función ‘aplica’ su primer
  argumento (una función) a los argumentos restantes, el último puede
  ser una lista.

#   For example,
  Por ejemplo,

#   ..src > elisp
#     (apply 'max 3 4 7 3 '(4 8 5))
#   < src..
  ..src > elisp
    (apply 'max 3 4 7 3 '(4 8 5))
  < src..

#   returns 8.
  devuelve 8

#   (Incidentally, I don't know how you would learn of this function without a
#   book such as this. It is possible to discover other functions, like
#   @c{search-forward} or @c{insert-rectangle}, by guessing at a part of their
#   names and then using @c{apropos}. Even though its base in metaphor is
#   clear––‘apply’ its first argument to the rest––I doubt a novice would come
#   up with that particular word when using @c{apropos} or other aid. Of
#   course, I could be wrong; after all, the function was first named by
#   someone who had to invent it.)
  (Por cierto, no cómo aprenderias sobre esta función sin un libro como este. Es
  posible descubrir otras funciones, como @c{search-forward} o
  @c{insert-rectangle}, adivinando una parte de sus nombres y luego usando
  @c{apropos}. Aunque su base metafórica es clara––‘apply’ @%i(aplicar) su primer
  argumento al resto––dudo que a un novato se le ocurra esa palabra en
  particular usando @c{apropos} u otra ayuda. Por supuesto, podría estar
  equivocado; después de todo, la función fué nombrada por primera vez por
  alguien que la tuvo que inventar.

#   The second and subsequent arguments to @c{apply} are optional, so we can
#   use @c{apply} to call a function and pass the elements of a list to it,
#   like this, which also returns 8:
  El segundo y siguientes argumentos de @c{apply} son opcionales, por lo que
  podemos usar @c{apply} para llamar a una función y pasarle los elementos de una
  lista, de la siguiente manera, que también devuelve 8:

#   ..src > elisp
#     (apply 'max '(4 8 5))
#   < src..
  ..src > elisp
    (apply 'max '(4 8 5))
  < src..

#   This latter way is how we will use @c{apply}. The
#   @c{recursive-lengths-list-many-files} function returns a numbers' list to
#   which we can apply @c{max} (we could also apply @c{max} to the sorted
#   numbers' list; it does not matter whether the list is sorted or not.)
  Este ultima forma es la que usaremos para @c{apply}. La función
  @c{lista-de-longitudes-de-muchos-ficheros-recursiva} devuelve una lista de
  números a la que podemos aplicar @c{max} (tambien podriamos aplicar @c(max) a
  la lista de números ordenados; no importa si la lista está ordenada o no).

#   Hence, the operation for finding the maximum height of the graph is this:
  Por lo tanto, la operación para encontrar la altura máxima del grafico es esta:

#   ..src > elisp
#     (setq max-graph-height (apply 'max numbers-list))
#   < src..
  ..src > elisp
    (setq altura-maxima-del-grafico (apply 'max lista-de-numeros))
  < src..

#   Now we can return to the question of how to create a list of strings for a
#   column of the graph. Told the maximum height of the graph and the number
#   of asterisks that should appear in the column, the function should return a
#   list of strings for the @c{insert-rectangle} command to insert.
  Ahora podemos volver a la pregunta de como crear una lista de cadenas para
  una columna del grafico. Indicando la máxima altura del grafico y el número de
  asteriscos que aparecerían en la columna, la función devolverá una lista de
  cadenas para el comando @c{insert-rectangle}.

#   Each column is made up of asterisks or blanks. Since the function is
#   passed the value of the height of the column and the number of asterisks in
#   the column, the number of blanks can be found by subtracting the number of
#   asterisks from the height of the column. Given the number of blanks and
#   the number of asterisks, two @c{while} loops can be used to construct the
#   list:
  Cada columna se compone de asteriscos o espacios en blanco. Puesto que pasamos
  a la función la altura de la columna y el número de asteriscos en ella, el
  número de espacios en blanco se puede encontrar restando los asteriscos de la
  altura. Dado el número de espacios en blanco y el número de asteriscos,
  podemos usar dos bucles @c{while} para construir la lista:

#   ..src > elisp
  ..src > elisp
#     ;;; First version.
    ;;; Primera versión.
#     (defun column-of-graph (max-graph-height actual-height)
    (defun columna-del-grafico (altura-maxima-del-grafico altura-real)
#       "Return list of strings that is one column of a graph."
      "Devuelve la lista de cadenas que es una columna de un grafico."
#       (let ((insert-list nil)
#             (number-of-top-blanks
#              (- max-graph-height actual-height)))
      (let ((lista-de-insercion nil)
            (numero-de-espacios
             (- altura-maxima-del-grafico altura-real)))

#         ;; Fill in asterisks.
        ;; Rellenar los asteriscos.
#         (while (> actual-height 0)
#           (setq insert-list (cons "*" insert-list))
#           (setq actual-height (1- actual-height)))
        (while (> altura-real 0)
          (setq lista-de-insercion (cons "*" lista-de-insercion))
          (setq altura-real (1- altura-real)))

#         ;; Fill in blanks.
        ;; Rellena los espacios.
#         (while (> number-of-top-blanks 0)
#           (setq insert-list (cons " " insert-list))
#           (setq number-of-top-blanks
#                 (1- number-of-top-blanks)))
        (while (> numero-de-espacios 0)
          (setq lista-de-insercion (cons " " lista-de-insercion))
          (setq numero-de-espacios
                (1- numero-de-espacios)))

#         ;; Return whole list.
        ;; Devuelve la lista completa.
#         insert-list))
        lista-de-insercion))
#   < src..
  < src..

#   If you install this function and then evaluate the following expression you
#   will see that it returns the list as desired:
  Si instalas esta función y luego evaluas la siguiente expresión, veras que
  devuelve la lista como se desea:

#   ..src > elisp
#     (column-of-graph 5 3)
#   < src..
  ..src > elisp
    (columna-del-grafico 5 3)
  < src..

#   returns
  devuelve

#   ..src > elisp
#     (" " " " "*" "*" "*")
#   < src..
  ..src > elisp
    (" " " " "*" "*" "*")
  < src..

#   As written, @c{column-of-graph} contains a major flaw: the symbols used for
#   the blank and for the marked entries in the column are ‘hard-coded’ as a
#   space and asterisk. This is fine for a prototype, but you, or another
#   user, may wish to use other symbols. For example, in testing the graph
#   function, you many want to use a period in place of the space, to make sure
#   the point is being repositioned properly each time the @c{insert-rectangle}
#   function is called; or you might want to substitute a @'{+} sign or other
#   symbol for the asterisk. You might even want to make a graph-column that
#   is more than one display column wide. The program should be more flexible.
#   The way to do that is to replace the blank and the asterisk with two
#   variables that we can call @c{graph-blank} and @c{graph-symbol} and define
#   those variables separately.
  Como está escrito, @c{columna-del-grafico} contiene un defecto importante:
  los símbolos usados para el espacio y las entradas marcadas en la columna
  estan ‘incrustados en el codigo’ como un espacio y un asterisco. Esto está
  bien para un prototipo, pero tu, u otro usuario, pueden querer usar otros
  símbolos. Por ejemplo, al probar la función del grafico, podrias querer usar
  un punto en vez del espacio, para asegurar que el punto se está colocando
  apropiadamente cada vez que se llama a la función @c{insert-rectangle}; o tal
  vez quieras sustituir un signo de asterisco por @'{+}. Incluso es posible
  querer crear un grafico de columna que tenga mas de una columna de
  visualizacion. El programa debería ser más flexible. La forma de hacerlo
  es reemplazar el espacio en blanco y el asterisco con dos variables que
  podemos llamar @c{simbolo-en-blanco} y @c{simbolo-grafico} y definir esa variables
  por separado.

#   Also, the documentation is not well written. These considerations lead us
#   to the second version of the function:
  Ademas, la documentación no está bien escrita. Estas consideraciones nos llevan
  a la segunda versión de la función:

#   ..src > elisp
  ..src > elisp
#     (defvar graph-symbol "*"
#       "String used as symbol in graph, usually an asterisk.")
    (defvar simbolo-grafico "*"
      "Cadena utilizada como símbolo en el grafico, normalmente un asterisco.")

#     (defvar graph-blank " "
#       "String used as blank in graph, usually a blank space.
#     graph-blank must be the same number of columns wide
#     as graph-symbol.")
    (defvar simbolo-en-blanco " "
      "Cadena utilizada como un espacio en blanco en el grafico, normalmente un espacio en blanco.
    simbolo-en-blanco debe tener el mismo número de columnas de ancho que simbolo-grafico.")
#   < src..
  < src..

#   (For an explanation of @c{defvar}, see Section @l{#Initializing a Variable
#   with @c{defvar}}.)
  (Para una explicación de @c{defvar}, consulta la seccion @l{#Inicializando una
  variable con @c{defvar}}.)

#   ..src > elisp
  ..src > elisp
#     ;;; Second version.
    ;;; Segunda versión.
#     (defun column-of-graph (max-graph-height actual-height)
    (defun columna-del-grafico (altura-maxima-del-grafico altura-real)
#       "Return MAX-GRAPH-HEIGHT strings; ACTUAL-HEIGHT are graph-symbols.
      "Devuelve cadenas con la ALTURA-MAXIMA-DEL-GRAFICO; ALTURA-REAL son símbolos graficos.

#     The graph-symbols are contiguous entries at the end
#     of the list.
#     The list will be inserted as one column of a graph.
#     The strings are either graph-blank or graph-symbol."
    Los simbolo-graficos son entradas contiguas al final de la lista.
    La lista se insertara como una columna de un grafico.
    Las cadenas contienen tanto simbolos en blanco como simbolos graficos."

#       (let ((insert-list nil)
#             (number-of-top-blanks
#              (- max-graph-height actual-height)))
      (let ((lista-de-insercion nil)
            (numero-de-espacios
             (- altura-maxima-del-grafico altura-real)))

#         ;; Fill in graph-symbols.
        ;; Rellena con simbolo-grafico.
#         (while (> actual-height 0)
#           (setq insert-list (cons graph-symbol insert-list))
#           (setq actual-height (1- actual-height)))
        (while (> altura-real 0)
          (setq lista-de-insercion (cons simbolo-grafico lista-de-insercion))
          (setq altura-real (1- altura-real)))

#         ;; Fill in graph-blanks.
        ;; Rellena con simbolo-en-blanco.
#         (while (> number-of-top-blanks 0)
#           (setq insert-list (cons graph-blank insert-list))
#           (setq number-of-top-blanks
#                 (1- number-of-top-blanks)))
        (while (> numero-de-espacios 0)
          (setq lista-de-insercion (cons simbolo-en-blanco lista-de-insercion))
          (setq numero-de-espacios
                (1- numero-de-espacios)))

#         ;; Return whole list.
#         insert-list))
        ;; Devuelve la lista completa.
        lista-de-insercion))
#   < src..
  < src..

#   If we wished, we could rewrite @c{column-of-graph} a third time to provide
#   optionally for a line graph as well as for a bar graph. This would not be
#   hard to do. One way to think of a line graph is that it is no more than a
#   bar graph in which the part of each bar that is below the top is blank. To
#   construct a column for a line graph, the function first constructs a list
#   of blanks that is one shorter than the value, then it uses @c{cons} to
#   attach a graph symbol to the list; then it uses @c{cons} again to attach
#   the ‘top blanks’ to the list.
  Si quisieramos, podríamos reescribir @c{columna-del-grafico} una tercera vez
  para proporcionar la opcion de crear un gráfico de líneas, como gráfico de
  barras. Esto no sería dificil de hacer. Una manera de pensar en un grafico de
  líneas es que no es más que un grafico de barras en el que la parte de cada
  barra que está debajo la parte superior esta en blanco. Para construir una
  columna para gráfico de líneas, la función primero construyen una lista de
  espacios en blanco que es más pequeña que el valor en uno, luego usa
  @c{cons} para adjuntar un símbolo gráfico a la lista; despues usa @c{cons} de
  nuevo para adjuntar el ‘alto de espacios en blanco’ a la lista.

#   It is easy to see how to write such a function, but since we don't need it,
#   we will not do it. But the job could be done, and if it were done, it
#   would be done with @c{column-of-graph}. Even more important, it is worth
#   noting that few changes would have to be made anywhere else. The
#   enhancement, if we ever wish to make it, is simple.
  Es fácil ver como escribir una función de este tipo, pero puesto que no la
  necesitamos, no se hará. Pero el trabajo podría hacerse, y si se hiciera, se
  haría con @c{columna-del-grafico}. Y lo que es más importante, señalar que
  pocos cambios tendrían que realizarce en otro lugar. La mejora,
  si alguna vez la hacemos, es simple.

#   Now, finally, we come to our first actual graph printing function. This
#   prints the body of a graph, not the labels for the vertical and horizontal
#   axes, so we can call this @c{graph-body-print}.
  Ahora, finalmente, llegamos a nuestra primer función real de impresion de
  graficos. Esta imprime el cuerpo de un grafico, no las etiquetas para los ejes
  horizontal y vertical, así que podemos nombrarla como @c{imprimir-cuerpo-grafico}.

# ** The @c{graph-body-print} Function
** La función @c{imprimir-cuerpo-grafico}

#    After our preparation in the preceding section, the @c{graph-body-print}
#    function is straightforward. The function will print column after column
#    of asterisks and blanks, using the elements of a numbers' list to specify
#    the number of asterisks in each column. This is a repetitive act, which
#    means we can use a decrementing @c{while} loop or recursive function for
#    the job. In this section, we will write the definition using a @c{while}
#    loop.
   Después de nuestra preparación en la sección anterior, la función
   @c{imprimir-cuerpo-grafico} es sencilla. La función imprimirá columna tras
   columna de asteriscos y espacios en blanco, usando los elementos de la
   lista de números para especificar el número de asteriscos en cada columna.
   Este es un acto repetitivo, lo que significa que podemos utilizar un bucle
   @c{while} decreciente o una función recursiva para el trabajo. En esta
   sección, escribiremos la definición usando un bucle @c{while}.

#    The @c{column-of-graph} function requires the height of the graph as an
#    argument, so we should determine and record that as a local variable.
   La función @c{columna-del-grafico} requiere como argumento la altura del
   grafico, por lo que debemos determinar y registrarla como una variable local.

#    This leads us to the following template for the @c{while} loop version of
#    this function:
   Esto nos lleva a la siguiente plantilla para la version con el bucle
   @c{while} de esta funcion:

#    ..src > elisp
   ..src > elisp
#      (defun graph-body-print (numbers-list)
     (defun imprimir-cuerpo-grafico (lista-de-numeros)
#        "documentation…"
       "documentacion…"
#        (let ((height  …
#               …))
       (let ((altura  …
              …))

#          (while numbers-list
         (while lista-de-numeros
#            insert-columns-and-reposition-point
           insertar-columna-y-reposicionar-punto
#            (setq numbers-list (cdr numbers-list)))))
           (setq lista-de-numeros (cdr lista-de-numeros)))))
#    < src..
   < src..

#    We need to fill in the slots of the template.
   Necesitamos completar los espacios de la plantilla.

#    Clearly, we can use the @c{(apply 'max numbers-list)} expression to
#    determine the height of the graph.
   Claramente, podemos usar la expresión @c{(apply 'max lista-de-numeros)} para
   determinar la altura del grafico.

#    The @c{while} loop will cycle through the @c{numbers-list} one element at
#    a time. As it is shortened by the @c{(setq numbers-list (cdr
#    numbers-list))} expression, the @c{car} of each instance of the list is
#    the value of the argument for @c{column-of-graph}.
   El bucle @c{while} recorrera la @c{lista-de-numeros} un elemento a la vez. A
   medida que se acorta la lista por la expresión @c{(setq lista-de-numeros (cdr
   lista-de-numeros))}, el @c{car} de cada instancia de la lista es el valor del
   argumento para @c{columna-del-grafico}.

#    At each cycle of the @c{while} loop, the @c{insert-rectangle} function
#    inserts the list returned by @c{column-of-graph}. Since the
#    @c{insert-rectangle} function moves point to the lower right of the
#    inserted rectangle, we need to save the location of point at the time the
#    rectangle is inserted, move back to that position after the rectangle is
#    inserted, and then move horizontally to the next place from which
#    @c{insert-rectangle} is called.
   En cada ciclo del bucle @c{while}, la función @c{insert-rectangle} inserta
   la lista devuelta por @c{columna-del-grafico}. Dado que la función
   @c{insert-rectangle}, mueve el punto a la parte inferior derecha del
   rectangulo insertado, necesitamos guardar la ubicacion del punto en el
   momento que se inserta el rectángulo, volver a esta posición después
   de insertar el rectángulo, y despues moverlo horizontalmente al
   siguiente lugar donde se llama a @c{insert-rectangle}.

#    If the inserted columns are one character wide, as they will be if single
#    blanks and asterisks are used, the repositioning command is simply
#    @c{(forward-char 1)}; however, the width of a column may be greater than
#    one. This means that the repositioning command should be written
#    @c{(forward-char symbol-width)}. The @c{symbol-width} itself is the
#    length of a @c{graph-blank} and can be found using the expression
#    @c{(length graph-blank)}. The best place to bind the @c{symbol-width}
#    variable to the value of the width of graph column is in the varlist of
#    the @c{let} expression.
   Si las columnas insertadas tienen un carácter de ancho, como será si se
   utilizan espacios y asteriscos unicos, el comando de reposicionamiento
   consiste solamente en @c{(forward-char 1)}; sin embargo, el ancho de una
   columna puede ser mayor que uno. Esto significa que el comando de
   reposicionamiento debe escribirse @c{(forward-char ancho-del-simbolo)}. El
   ancho del simbolo en si es la longitud de un grafico en blanco y se puede
   encontrar usando la expresion @c{(length graph-blank)}. El mejor lugar para
   asociar la variable @c{ancho-del-simbolo} al valor de la columna
   de grafico está en la varlist de la expresión @c{let}.

#    These considerations lead to the following function definition:
   Estas consideraciones conducen a la siguiente definición de función:

#    ..src > elisp
   ..src > elisp
#      (defun graph-body-print (numbers-list)
     (defun imprimir-cuerpo-grafico (lista-de-numeros)
#        "Print a bar graph of the NUMBERS-LIST.
#      The numbers-list consists of the Y-axis values."
       "Imprime un gráfico de barras de la LISTA-DE-NUMEROS.
     La lista-de-numeros esta formada por los valores del eje Y."

#        (let ((height (apply 'max numbers-list))
       (let ((altura (apply 'max lista-de-numeros))
#              (symbol-width (length graph-blank))
#              from-position)
             (ancho-del-simbolo (length simbolo-en-blanco))
             desde-la-posicion)

#          (while numbers-list
         (while lista-de-numeros
#            (setq from-position (point))
#            (insert-rectangle
#             (column-of-graph height (car numbers-list)))
           (setq desde-la-posicion (point))
           (insert-rectangle
            (columna-del-grafico altura (car lista-de-numeros)))
#            (goto-char from-position)
#            (forward-char symbol-width)
           (goto-char desde-la-posicion)
           (forward-char ancho-del-simbolo)
#            ;; Draw graph column by column.
           ;; Dibuja el grafico columna por columna.
#            (sit-for 0)
#            (setq numbers-list (cdr numbers-list)))
           (sit-for 0)
           (setq lista-de-numeros (cdr lista-de-numeros)))
#          ;; Place point for X axis labels.
         ;; Coloca el punto para las etiquetas del eje X.
#          (forward-line height)
#          (insert "\n")
         (forward-line altura)
         (insert "\n")
#      ))
     ))
#    < src..
   < src..

#    The one unexpected expression in this function is the @c{(sit-for 0)}
#    expression in the @c{while} loop. This expression makes the graph
#    printing operation more interesting to watch than it would be otherwise.
#    The expression causes Emacs to ‘sit’ or do nothing for a zero length of
#    time and then redraw the screen. Placed here, it causes Emacs to redraw
#    the screen column by column. Without it, Emacs would not redraw the
#    screen until the function exits.
   La unica expresión inesperada en esta función es @c{(sit-for 0)} dentro del
   bucle @c{while}. Esta expresión hace que la operacion de impresion de
   graficos sea más de lo que sería de otro modo. La expresión hace que Emacs
   @'(pare) @%i(sit) o no haga nada un periodo de tiempo cero y luego vuelva a
   dibujar la pantalla. Puesto aquí, hace que Emacs redibuje la pantalla
   columna por columna. Sin ella, Emacs no redibujaría la pantalla hasta que la
   función termine.

#    We can test @c{graph-body-print} with a short list of numbers.
   Podemos probar @c{imprimir-cuerpo-grafico} con una pequeña lista de números.

#    1. Install @c{graph-symbol}, @c{graph-blank}, @c{column-of-graph}, which
#       are in Section @l{#Readying a Graph}, and @l{#The @c{graph-body-print} Function}.
   1. Instala @c{simbolo-grafico}, @c{simbolo-en-blanco}, @c{columna-del-grafico}, que
      aparecen en las Secciones @l{#Preparar un grafico}, y @c{#La función @c{imprimir-cuerpo-grafico}}.

#    2. Copy the following expression:
   2. Copia la siguiente expresión:

#       ..src > elisp
#         (graph-body-print '(1 2 3 4 6 4 3 5 7 6 5 2 3))
#       < src..
      ..src > elisp
        (imprimir-cuerpo-grafico '(1 2 3 4 6 4 3 5 7 6 5 2 3))
      < src..

#    3. Switch to the @f{*scratch*} buffer and place the cursor where you want
#       the graph to start.
   3. Cambia al búfer @f{*scratch*} y coloca el cursor donde quieras que empiece
      el grafico.

#    4. Type @k{M-:} @%c(eval-expression).
   4. Pulsa @k{M-:} @%c(eval-expression).

#    5. Yank the @c{graph-body-print} expression into the minibuffer with
#       @k{C-y} @%c(yank).
   5. Pega la expresión @c{imprimir-cuerpo-grafico} dentro del minibúfer con
      @k{C-y} @%c(yank).

#    6. Press @k{RET} to evaluate the @c{graph-body-print} expression.
   6. Presiona @k{RET} para evaluar la expresión @c{imprimir-cuerpo-grafico}.


#    Emacs will print a graph like this:
   Emacs imprimirá un grafico como este:

#    ..example >
#              *
#          *   **
#          *  ****
#         *** ****
#        ********* *
#       ************
#      *************
#    < example..
   ..example >
             *
         *   **
         *  ****
        *** ****
       ********* *
      ************
     *************
   < example..

# ** The @c{recursive-graph-body-print} Function
** La función @c{imprimir-cuerpo-grafico-con-recursividad}

#    The @c{graph-body-print} function may also be written recursively. The
#    recursive solution is divided into two parts: an outside ‘wrapper’ that
#    uses a @c{let} expression to determine the values of several variables
#    that need only be found once, such as the maximum height of the graph, and
#    an inside function that is called recursively to print the graph.
   La función @c{imprimir-cuerpo-grafico} también puede escribirse
   recursivamente. La solución recursiva se divide en dos partes: una
   @'(envoltura) externa que utiliza una expresión @c{let} para determinar los
   valores de varias variables que solo es necesario encontrar una vez, como la
   altura máxima del grafico, y una función interna que se llama recursivamente
   para imprimir el grafico.

#    The ‘wrapper’ is uncomplicated:
   La ‘envoltura’ no es complicada:

#    ..src > elisp
   ..src > elisp
#      (defun recursive-graph-body-print (numbers-list)
     (defun imprimir-cuerpo-grafico-con-recursividad (lista-de-numeros)
#        "Print a bar graph of the NUMBERS-LIST.
       "Imprime un gráfico de barras de la LISTA-DE-NUMEROS.
#      The numbers-list consists of the Y-axis values."
     La lista-de-numeros esta formada por los valores del eje Y."
#        (let ((height (apply 'max numbers-list))
#              (symbol-width (length graph-blank))
#              from-position)
       (let ((altura (apply 'max lista-de-numeros))
             (ancho-del-simbolo (length simbolo-en-blanco))
             desde-la-posicion)
#          (recursive-graph-body-print-internal
#           numbers-list
#           height
#           symbol-width)))
         (imprimir-cuerpo-grafico-con-recursividad-interna
          lista-de-numeros
          altura
          ancho-del-simbolo)))
#    < src..
   < src..

#    The recursive function is a little more difficult. It has four parts: the
#    ‘do-again-test’, the printing code, the recursive call, and the
#    ‘next-step-expression’. The ‘do-again-test’ is a @c{when} expression that
#    determines whether the @c{numbers-list} contains any remaining elements;
#    if it does, the function prints one column of the graph using the printing
#    code and calls itself again. The function calls itself again according to
#    the value produced by the ‘next-step-expression’ which causes the call to
#    act on a shorter version of the @c{numbers-list}.
   La función recursiva es un poco más difícil. Tiene cuatro partes: la
   ‘prueba-hazlo-de-nuevo’, el código de impresion, la llamada recursiva, y la
   ‘expresion-del-siguiente-paso’. La ‘prueba-hazlo-de-nuevo’ es una expresión
   @c{when} que determina si la @c{lista-de-numeros} contiene algun elemento
   restante; si lo tiene, la función imprime una columna del grafico usando el
   código de impresion y se vuelve a llamar asi misma. La función se llama así
   misma de acuerdo al valor producido por la ‘expresion-del-siguiente-paso’
   que hace que la llamada actue sobre una versión mas corta de la
   @c{lista-de-numeros}.

#    ..src > elisp
   ..src > elisp
#      (defun recursive-graph-body-print-internal
#        (numbers-list height symbol-width)
     (defun imprimir-cuerpo-grafico-con-recursividad-interna
       (lista-de-numeros altura ancho-del-simbolo)
#        "Print a bar graph.
#      Used within recursive-graph-body-print function."
       "Imprime un gráfico de barras.
     Se utiliza dentro del cuerpo de la función imprimir-cuerpo-grafico-con-recursividad."

#        (when numbers-list
       (when lista-de-numeros
#              (setq from-position (point))
             (setq desde-la-posicion (point))
#              (insert-rectangle
             (insert-rectangle
#               (column-of-graph altura (car numbers-list)))
              (columna-del-grafico altura (car lista-de-numeros)))
#              (goto-char from-position)
#              (forward-char symbol-width)
             (goto-char desde-la-posicion)
             (forward-char ancho-del-simbolo)
#              (sit-for 0)     ; Draw graph column by column.
             (sit-for 0)     ; Dibuja el gráfico columna por columna.
#              (recursive-graph-body-print-internal
#               (cdr numbers-list) altura symbol-width)))
             (imprimir-cuerpo-grafico-con-recursividad-interna
              (cdr lista-de-numeros) altura ancho-del-simbolo)))
#    < src..
   < src..

#    After installation, this expression can be tested; here is a sample:
   Podemos probar esta expresión después de instalarla; aquí hay un ejemplo:

#    ..src > elisp
#      (recursive-graph-body-print '(3 2 5 6 7 5 3 4 6 4 3 2 1))
#    < src..
   ..src > elisp
     (imprimir-cuerpo-grafico-con-recursividad '(3 2 5 6 7 5 3 4 6 4 3 2 1))
   < src..

#    Here is what @c{recursive-graph-body-print} produces:
   Aquí está el resultado:

#    ..example >
#          *
#         **   *
#        ****  *
#        **** ***
#      * *********
#      ************
#      *************
#    < example..
   ..example >
         *
        **   *
       ****  *
       **** ***
     * *********
     ************
     *************
   < example..

#    Either of these two functions, @c{graph-body-print} or
#    @c{recursive-graph-body-print}, create the body of a graph.
   Cada una de estas dos funciones, @c{imprimir-cuerpo-grafico} o
   @c{imprimir-cuerpo-grafico-con-recursividad}, crea el cuerpo de un grafico.

# ** Need for Printed Axes
** Necesidad de Ejes Impresos

#    A graph needs printed axes, so you can orient yourself. For a do-once
#    project, it may be reasonable to draw the axes by hand using Emacs's
#    Picture mode; but a graph drawing function may be used more than once.
   Un grafico necesita ejes impresos para poder orientarse. Para un
   proyecto de usar una vez, puede ser razonable dibujar los ejes a mano usando
   el modo Picture de emacs, pero una funcion de dibujo de graficos puede usarse
   más de una vez.

#    For this reason, I have written enhancements to the basic
#    @c{print-graph-body} function that automatically print labels for the
#    horizontal and vertical axes. Since the label printing functions do not
#    contain much new material, I have placed their description in an appendix.
#    See Section @l{#Appendix C: A Graph with Labeled Axes}.
   Por esta razón, he escrito mejoras a la función básica
   @c{print-graph-body} que imprime automáticamente etiquetas para los ejes
   horizontal y vertical. Como las funciones de impresion de etiquetas no
   contiene mucho material nuevo, he puesto su descripción en un
   apéndice. Ver Seccion @l{#Apéndice C: Un grafico con ejes etiquetados}.

# ** Exercise
** Ejercicio

#    Write a line graph version of the graph printing functions.
   Escribe una versión de grafico de lineas de las funciones de impresión de
   graficos.

# * Your @f{.emacs} File
* Tu fichero @f{.emacs}

#   “You don't have to like Emacs to like it”––this seemingly paradoxical
#   statement is the secret of GNU Emacs. The plain, ‘out of the box’ Emacs is
#   a generic tool. Most people who use it, customize it to suit themselves.
  “No te tiene que gustar Emacs para que te guste”––esta declaracion
  aparentemente paradójica es el secreto de GNU Emacs. En realidad, Emacs es una
  herramienta genérica. La mayoría de las personas que lo usan, lo personalizan
  para ajustarlo a sus necesidades.

#   GNU Emacs is mostly written in Emacs Lisp; this means that by writing
#   expressions in Emacs Lisp you can change or extend Emacs.
  GNU Emacs está escrito principalmente en Emacs Lisp; esto significa que
  escribiendo expresiones en Emacs Lisp se puede modificar o extender Emacs.

#   There are those who appreciate Emacs's default configuration. After all,
#   Emacs starts you in C mode when you edit a C file, starts you in Fortran
#   mode when you edit a Fortran file, and starts you in Fundamental mode when
#   you edit an unadorned file. This all makes sense, if you do not know who
#   is going to use Emacs. Who knows what a person hopes to do with an
#   unadorned file?  Fundamental mode is the right default for such a file,
#   just as C mode is the right default for editing C code.  (Enough
#   programming languages have syntaxes that enable them to share or nearly
#   share features, so C mode is now provided by CC mode, the ‘C Collection’.)
  Hay quienes aprecian la configuración por defecto de Emacs. Después de todo,
  Emacs inicia en modo C cuando se edita un fichero C, inicia en modo Fortran
  cuando se edita un fichero Fortran, y en modo Fundamental cuando se edita un
  fichero sin adornos. Esto tiene sentido, si no sabes quien va a utilizar
  Emacs. ¿Quién sabe lo que una persona espera hacer con un fichero sin adornos?
  Para dicho fichero, el modo fundamental es el modo por defecto apropiado, de
  la misma manera C es el modo predeterminado correcto para editar código
  C. (Hay suficientes lenguajes de programación con sintaxis que permiten
  compartir funcionalidades, por lo que el modo C ahora se proporciona para el
  modo CC, ‘C Collection’.)

#   But when you do know who is going to use Emacs––you, yourself––then it
#   makes sense to customize Emacs.
  Pero cuando sabes quien va a utilizar Emacs––tu mismo––entonces
  tiene sentido personalizar Emacs.

#   For example, I seldom want Fundamental mode when I edit an otherwise
#   undistinguished file; I want Text mode. This is why I customize Emacs: so
#   it suits me.
  Por ejemplo, rara vez quiero el modo Fundamental cuando edito un
  fichero que de otro modo no se distinguiria; quiero el modo Text. Por eso
  personalizo Emacs: para que se adapte a mí.

#   You can customize and extend Emacs by writing or adapting a @f{~/.emacs}
#   file. This is your personal initialization file; its contents, written in
#   Emacs Lisp, tell Emacs what to do.@n{14}
  Puedes personalizar y ampliar Emacs escribiendo o adaptando un fichero
  @f{~/.emacs}. Este es tu fichero de inicialización personal; su
  contenido, escrito en Emacs Lisp, le indica a Emacs qué hacer.@n{14}

#   A @f{~/.emacs} file contains Emacs Lisp code. You can write this code
#   yourself; or you can use Emacs's @c{customize} feature to write the code
#   for you. You can combine your own expressions and auto-written Customize
#   expressions in your @f{.emacs} file.
  Un fichero @f{~/.emacs} contiene código Emacs Lisp. Puedes escribir este
  código tu mismo; o usar la funcion de Emacs @c{customize} para
  que escriba el código por ti. Puedes combinar tus propias expresiones y
  expresiones auto-escritas en tu fichero @f{.emacs}.

#   (I myself prefer to write my own expressions, except for those,
#   particularly fonts, that I find easier to manipulate using the
#   @c{customize} command. I combine the two methods.)
  (Yo prefiero escribir mis propias expresiones, excepto aquellas,
  particularmente las fuentes, que encuentro mas fáciles de manipular usando el
  comando @c{customize}. Combino los dos métodos.)

#   Most of this chapter is about writing expressions yourself. It describes a
#   simple @f{.emacs} file; for more information, see Section
#   @l{emacs.html#Init File<>The Init File} in @e(The GNU Emacs Manual), and
#   Section @l{elisp.html#Init File<>The Init File} in @e{The GNU Emacs Lisp
#   Reference Manual}.
  La mayor parte de este capítulo trata sobre como escribir expresiones por uno
  mismo. Describe un fichero @f{.emacs} simple; para más información, consulta la Sección
  @l{emacs.html#Init File<>El fichero de inicio} en @e(El Manual de GNU Emacs),
  y la Seccion @l{elisp.html#Init File<>El fichero de inicio} en @e(El Manual de
  Referencia GNU Emacs Lisp).

# ** Site-wide Initialization Files
** Ficheros de inicialización site-wide

#    In addition to your personal initialization file, Emacs automatically
#    loads various site-wide initialization files, if they exist. These have
#    the same form as your @f{.emacs} file, but are loaded by everyone.
   Además de tu fichero de inicialización personal, Emacs carga automáticamente
   varios ficheros de inicialización, si existen. Estos tienen la misma forma
   que tu fichero @f{.emacs}, pero se cargan para todos.

#    Two site-wide initialization files, @f{site-load.el} and @f{site-init.el},
#    are loaded into Emacs and then ‘dumped’ if a ‘dumped’ version of Emacs is
#    created, as is most common.  (Dumped copies of Emacs load more quickly.
#    However, once a file is loaded and dumped, a change to it does not lead to
#    a change in Emacs unless you load it yourself or re-dump Emacs. See
#    Section @l{elisp.html#Building Emacs<>Building Emacs} in @e{The GNU Emacs
#    Lisp Reference Manual}, and the @f{INSTALL} file.)
   Dos ficheros de incialización para todos los usuarios, @f{site-load.el} y
   @f{site-init.el}, se cargan en Emacs y luego se @'(vuelcan) si se crea una
   version @'(volcada) de Emacs, como es más común. (Las copias volcadas de
   Emacs se cargan más rápidamente. Sin embargo, una vez que un fichero se carga
   y vuelca, un cambio en el no conduce a un cambio en Emacs a menos que lo
   cargues por tu cuenta. Consulta la Seccion @l{elisp.html#Building
   Emacs<>Construyendo Emacs} en @e(El Manual de Referencia de GNU Emacs Lisp), y
   el fichero @f{INSTALL)}

#    Three other site-wide initialization files are loaded automatically each
#    time you start Emacs, if they exist. These are @f{site-start.el}, which
#    is loaded @e{before} your @f{.emacs} file, and @f{default.el}, and the
#    terminal type file, which are both loaded @e{after} your @f{.emacs} file.
   Otros tres ficheros de inicialización se cargan automáticamente cada
   vez que se inicia Emacs, si existen. Son @f{site-start.el}, que se carga
   @e{antes} que tu fichero @f{.emacs}, y @f{default.el}, y el fichero de tipo de
   terminal, que se cargan @e{después} de @f{.emacs}.

#    Settings and definitions in your @f{.emacs} file will overwrite
#    conflicting settings and definitions in a @f{site-start.el} file, if it
#    exists; but the settings and definitions in a @f{default.el} or terminal
#    type file will overwrite those in your @f{.emacs} file.  (You can prevent
#    interference from a terminal type file by setting @c{term-file-prefix} to
#    @c{nil}. See Section @l{#A Simple Extension: @c{line-to-top-of-window}}.)
   Las configuraciones y definiciones en tu fichero @f{.emacs} sobreescribirán
   las configuraciones y definiciones conflictivas del fichero @f{site-start.el},
   si existe; pero las configuraciones y definiciones en @f{default.el} o el
   fichero de tipo de terminal sobreescribirán las de @f{.emacs}. (puede
   evitar las interferencias del fichero de tipo de terminal configurando
   @c{term-file-prefix} a @c{nil}. Consulta la Seccion @l{#Una extensión simple:
   @c{linea-a-lo-alto-de-la-ventana}}.)

#    The @f{INSTALL} file that comes in the distribution contains descriptions
#    of the @f{site-init.el} and @f{site-load.el} files.
   El fichero @f{INSTALL} que viene en la distribución contiene descripciones
   de los ficheros @f{site-init.el} y @f{site-load.el}.

#    The @f{loadup.el}, @f{startup.el}, and @f{loaddefs.el} files control
#    loading. These files are in the @f{lisp} directory of the Emacs
#    distribution and are worth perusing.
   Los ficheros @f{loadup.el}, @f{startup.el}, y @f{loaddefs.el} controlan la
   carga. Estos ficheros están en el directorio @f{lisp} de la distribución
   Emacs y vale la pena leerlos.

#    The @f{loaddefs.el} file contains a good many suggestions as to what to
#    put into your own @f{.emacs} file, or into a site-wide initialization
#    file.
   El fichero @f{loaddefs.el} contiene muchas sugerencias sobre que poner en tu
   propio fichero @f{.emacs}, o dentro de un fichero de inicialización amplio.

# ** Specifying Variables using @c{defcustom}
** Especificar variables usando @c{defcustom}

#    You can specify variables using @c{defcustom} so that you and others can
#    then use Emacs's @c{customize} feature to set their values.  (You cannot
#    use @c{customize} to write function definitions; but you can write
#    @c{defuns} in your @f{.emacs} file. Indeed, you can write any Lisp
#    expression in your @f{.emacs} file.)
   Puedes especificar variables usando @c{defcustom} para que tu y otros puedan
   usar la caracteristica de Emacs @c{customize} para establecer sus valores.
   (No se puede usar @c{customize} para escribir definiciones de función; pero
   se pueden escribir @c{defuns} en el fichero @f{.emacs}. De hecho, se puede
   escribir cualquier expresión Lisp en el fichero @f{.emacs}).

#    The @c{customize} feature depends on the @c{defcustom} special form.
#    Although you can use @c{defvar} or @c{setq} for variables that users set,
#    the @c{defcustom} special form is designed for the job.
   La caracteristicas de configuracion ofrecidas por @c{customize} dependen de la
   forma especial @c{defcustom}. Aunque se puede usar @c{defvar} o @c{setq} para
   las variables que establecen los usuarios, la forma especial @c{defcustom} está
   diseñada para este trabajo.

#    You can use your knowledge of @c{defvar} for writing the first three
#    arguments for @c{defcustom}. The first argument to @c{defcustom} is the
#    name of the variable. The second argument is the variable's initial
#    value, if any; and this value is set only if the value has not already
#    been set. The third argument is the documentation.
   Puedes usar tu conocimiento de @c{defvar} para escribir los primeros
   tres argumentos de @c{defcustom}. El primer argumento de @c{defcustom}
   es el nombre de la variable. El segundo argumento es el valor inicial de
   la variable, si lo hay; y este valor se asigna solo si el valor no se ha
   establecido. El tercer argumento es la documentación.

#    The fourth and subsequent arguments to @c{defcustom} specify types and
#    options; these are not featured in @c{defvar}.  (These arguments are
#    optional.)
   El cuarto y subsiguientes argumentos de @c{defcustom} especifican
   tipos y opciones; estos no se presentan en @c{defvar}. (Estos
   argumentos son opcionales.)

#    Each of these arguments consists of a keyword followed by a value. Each
#    keyword starts with the colon character @'{:}.
   Cada uno de estos argumentos consiste de una palabra clave seguida de un
   valor. Cada palabra clave empieza con el caracter dos puntos @'{:}.

#    For example, the customizable user option variable @c{text-mode-hook}
#    looks like this:
   Por ejemplo, la variable de opciones personalizable @c{text-mode-hook} tiene
   el siguiente aspecto:

#    ..src > elisp
#      (defcustom text-mode-hook nil
#        "Normal hook run when entering Text mode and many related modes."
#        :type 'hook
#        :options '(turn-on-auto-fill flyspell-mode)
#        :group 'wp)
#    < src..
   ..src > elisp
     (defcustom text-mode-hook nil
       "El hook normal se ejecuta cuando se ingresa en modo texto y en muchos modos relacionados."
       :type 'hook
       :options '(turn-on-auto-fill flyspell-mode)
       :group 'wp)
   < src..

#    The name of the variable is @c{text-mode-hook}; it has no default value;
#    and its documentation string tells you what it does.
   El nombre de la variable es @c{text-mode-hook}; no tiene valor por
   defecto; y su cadena de documentación cuenta lo que hace.

#    The @c{:type} keyword tells Emacs the kind of data to which
#    @c{text-mode-hook} should be set and how to display the value in a
#    Customization buffer.
   La palabra clave @c{:type} le indica a Emacs el tipo de datos a los que
   @c{text-mode-hook} sera asignado y como mostrar el valor en un búfer
   de personalización.

#    The @c{:options} keyword specifies a suggested list of values for the
#    variable. Usually, @c{:options} applies to a hook. The list is only a
#    suggestion; it is not exclusive; a person who sets the variable may set it
#    to other values; the list shown following the @c{:options} keyword is
#    intended to offer convenient choices to a user.
   La palabra clave @c{:options} especifica una lista sugerida de valores para
   la variable. Normalmente, @c{:options} se asocia a un @"(gancho)
   @%i(hook). La lista es solo una sugerencia; no es excluyente; una persona que
   establece la variable puede establecerla en otros valores; la lista que se
   muestra despues de la palabra clave @c{:options} tiene la intencion de
   ofrecer opciones convenientes a el usuario.

#    Finally, the @c{:group} keyword tells the Emacs Customization command in
#    which group the variable is located. This tells where to find it.
   Finalmente, la palabra clave @c{:group} indica al comando de Personalización
   de Emacs en que el grupo se encuentra la variable. Esto dice dónde encontrala.

#    The @c{defcustom} function recognizes more than a dozen keywords. For
#    more information, see Section @l{elisp.html#Customization<>Writing
#    Customization Definitions} in @e{The GNU Emacs Lisp Reference Manual}.
   La función @c{defcustom} reconoce más de una docena de palabras clave. Para
   obtener más información, consulta la Seccion @l{elisp.html#Customization<>Escribir
   las Definiciones de Personalización} en @e(El Manual de Referencia GNU Emacs
   Lisp).

#    Consider @c{text-mode-hook} as an example.
   Considera @c{text-mode-hook} como un ejemplo.

#    There are two ways to customize this variable. You can use the
#    customization command or write the appropriate expressions yourself.
   Hay dos maneras de personalizar esta variable. Puedes utilizar el comando
   de personalización o escribir las expresiones apropiadas por tu cuenta.

#    Using the customization command, you can type:
   Utilizando el comando de personalización, puedes escribir:

#    ..example >
#      M-x customize
#    < example..
   ..example >
     M-x customize
   < example..

#    and find that the group for editing files of data is called ‘data’. Enter
#    that group. Text Mode Hook is the first member. You can click on its
#    various options, such as @c{turn-on-auto-fill}, to set the values. After
#    you click on the button to
   y encontrar que el grupo para editar ficheros de datos se llama
   ‘data’. Introduce este grupo. El Gancho del Modo Text es el primer
   miembro. Puedes hacer click en sus varias opciones, como
   @c{turn-on-auto-fill}, para establecer los valores. Después de hacer click en
   el botón.

#    ..example >
#      Save for Future Sessions
#    < example..
   ..example >
     Guárdar para sesiones futuras
   < example..

#    Emacs will write an expression into your @f{.emacs} file. It will look
#    like this:
   Emacs escribirá una expresión en tu fichero @f{.emacs}. Se vera asi:

#    ..src > elisp
#      (custom-set-variables
#        ;; custom-set-variables was added by Custom.
#        ;; If you edit it by hand, you could mess it up, so be careful.
#        ;; Your init file should contain only one such instance.
#        ;; If there is more than one, they won't work right.
#       '(text-mode-hook (quote (turn-on-auto-fill text-mode-hook-identify))))
#    < src..
   ..src > elisp
     (custom-set-variables
       ;; custom-set-variables fué añadido por Custom.
       ;; Si lo editas a mano, podrías estropearlo, así que ten cuidado.
       ;; Tu fichero init deberia contener solo una de esta instancia.
       ;; Si hay más de una, no funcionara bien.
      '(text-mode-hook (quote (turn-on-auto-fill text-mode-hook-identify))))
   < src..

#    (The @c{text-mode-hook-identify} function tells
#    @c{toggle-text-mode-auto-fill} which buffers are in Text mode. It comes
#    on automatically.)
   (La función @c{text-mode-hook-identify} le indica a
   @c{toggle-text-mode-auto-fill} que buffers estan en modo Texto. Se encendera
   automáticamente)

#    The @c{custom-set-variables} function works somewhat differently than a
#    @c{setq}. While I have never learned the differences, I modify the
#    @c{custom-set-variables} expressions in my @f{.emacs} file by hand: I make
#    the changes in what appears to me to be a reasonable manner and have not
#    had any problems. Others prefer to use the Customization command and let
#    Emacs do the work for them.
   La función @c{custom-set-variables} funciona de una manera algo distinta a
   @c{setq}. Aunque nunca he aprendido las diferencias, modifico las expresiones
   @c{custom-set-variable} en mi fichero @f{.emacs} a mano: Hago los cambios de
   la forma que me parecen razonables y no he tenido ningun problema. Otros
   prefieren usar el comando de Personalización y dejar que Emacs haga el
   trabajo por ellos.

#    Another @c{custom-set-…} function is @c{custom-set-faces}. This function
#    sets the various font faces. Over time, I have set a considerable number
#    of faces. Some of the time, I re-set them using @c{customize}; other
#    times, I simply edit the @c{custom-set-faces} expression in my @f{.emacs}
#    file itself.
   Otra función de @c{custom-set-…} es @c{custom-set-faces}. Esta función
   establece varios tipos de fuentes. Con el tiempo, he asignado un considerable
   número de fuentes. Algunas veces, las reseteo usando @c{customize}; otras
   veces, simplemente edito la expresión @c{custom-set-faces} en mi fichero
   @f{.emacs}.

#    The second way to customize your @c{text-mode-hook} is to set it yourself
#    in your @f{.emacs} file using code that has nothing to do with the
#    @c{custom-set-…} functions.
   La segunda forma de personalizar @c{text-mode-hook} es configurarlo
   directamente en tu fichero @f{.emacs} usando código que no tiene nada que
   ver con las funciones @c{custom-set-…}.

#    When you do this, and later use @c{customize}, you will see a message that
#    says
   Al hacer esto, y mas tarde usar @c{customize}, verás un mensaje que
   dice:

#    ..example >
#      CHANGED outside Customize; operating on it here may be unreliable.
#    < example..
   ..example >
     CAMBIADO fuera de Customize; operar con el aquí puede no ser confiable.
   < example..

#    This message is only a warning. If you click on the button to
   Este mensaje es solo una advertencia. Si se cliquear en el botón

#    ..example >
#      Save for Future Sessions
#    < example..
   ..example >
     Guárdar para sesiones futuras
   < example..

#    Emacs will write a @c{custom-set-…} expression near the end of your
#    @f{.emacs} file that will be evaluated after your hand-written expression.
#    It will, therefore, overrule your hand-written expression. No harm will
#    be done. When you do this, however, be careful to remember which
#    expression is active; if you forget, you may confuse yourself.
   Emacs escribirá una expresión @c{custom-set-…} cerca del fin de tu fichero
   @f{.emacs} que será evaluada después de la expresión escrita a mano. Por
   lo tanto, invalidará tu expresión escrita a mano. No se hara ningún daño.
   Sin embargo, cuando hagas esto, ten cuidado para recordar que expresión
   está activa; si lo olvidas, puedes confundirte.

#    So long as you remember where the values are set, you will have no
#    trouble. In any event, the values are always set in your initialization
#    file, which is usually called @f{.emacs}.
   Siempre y cuando recuerdes donde estan establecidos los valores, no habrá
   ningun problema. En cualquier caso, los valores siempre se establecen en tu
   fichero de inicialización, que suele llamarse @f{.emacs}.

#    I myself use @c{customize} for hardly anything. Mostly, I write
#    expressions myself.
   Yo mismo casi nunca uso @c{customize}. Mayoritariamente,
   escribo las expresiones por mí cuenta.

#    Incidentally, to be more complete concerning defines: @c{defsubst} defines
#    an inline function. The syntax is just like that of @c{defun}.
#    @c{defconst} defines a symbol as a constant. The intent is that neither
#    programs nor users should ever change a value set by @c{defconst}.  (You
#    can change it; the value set is a variable; but please do not.)
   Por cierto, para ser mas completo con respecto a las definiciones:
   @c{defsubst} define una función inline. La sintaxis es igual a la de
   @c{defun}. @c{defconst} define un símbolo como una constante. La intencion
   es que ni los programas ni los usuarios cambien nunca un valor establecido por
   @c{defconst}. (Puede cambiarse; el valor se asigna a una variable; pero
   por favor no lo hagas.)

# ** Beginning a @f{.emacs} File
** Empieza por un fichero @f{.emacs}

#    When you start Emacs, it loads your @f{.emacs} file unless you tell it not
#    to by specifying @c{-q} on the command line.  (The @${emacs -q} command
#    gives you a plain, out-of-the-box Emacs.)
   Cuando inicia Emacs, carga tu fichero @f{.emacs} a menos que se indique
   que no lo haga especificando @c{-q} en la línea de comandos. (El comando @${emacs
   -q} te da un Emacs limpio, y listo para usar.)

#    A @f{.emacs} file contains Lisp expressions. Often, these are no more
#    than expressions to set values; sometimes they are function definitions.
   Un fichero @f{.emacs} contiene expresiones Lisp. Con frecuencia, no son
   más que expresiones para establecer valores; algunas veces son
   definiciones de funcion.

#    See Section @l{emacs.html#Init File<>The Init File @f{~/.emacs}} in @e(The
#    GNU Emacs Manual), for a short description of initialization files.
   Consulta la Seccion @l{emacs.html#Init File<>El Fichero de Inicio @f{~/.emacs}} en
   @e(El Manual de GNU Emacs), para una breve descripción de los fichero de
   inicialización.

#    This chapter goes over some of the same ground, but is a walk among
#    extracts from a complete, long-used @f{.emacs} file––my own.
   Este capítulo pasa por el mismo terreno, pero es un paseo entre extractos
   de un fichero @f{.emacs} completo––el mio.

#    The first part of the file consists of comments: reminders to myself. By
#    now, of course, I remember these things, but when I started, I did not.
   La primera parte del fichero consiste en comentarios: recordatorios a mí
   mismo. Por ahora, por supuesto, recuerdo estas cosas, pero cuando empecé, no
   lo hice.

#    ..src > elisp
#      ;;;; Bob's .emacs file
#      ; Robert J. Chassell
#      ; 26 September 1985
#    < src..
   ..src > elisp
     ;;;; fichero .emacs de Bob
     ; Robert J. Chassell
     ; 26 de Septiembre de 1985
   < src..

#    Look at that date!  I started this file a long time ago. I have been
#    adding to it ever since.
   ¡Mira esa fecha! Empecé este fichero hace mucho tiempo. Lo he
   estado extendiendo desde entonces.

#    ..src > elisp
#      ; Each section in this file is introduced by a
#      ; line beginning with four semicolons; and each
#      ; entry is introduced by a line beginning with
#      ; three semicolons.
#    < src..
   ..src > elisp
     ; Cada sección en este fichero se inicia por una
     ; línea empezando con cuatro punto y coma y cada
     ; entrada inicia por una línea empezando con
     ; tres punto y coma.
   < src..

#    This describes the usual conventions for comments in Emacs Lisp.
#    Everything on a line that follows a semicolon is a comment. Two, three,
#    and four semicolons are used as subsection and section markers.  (See
#    Section @l{elisp.html#Comments<>Comments} in @e{The GNU Emacs Lisp
#    Reference Manual}, for more about comments.)
   Esto describe las convenciones habituales para comentarios en Emacs
   Lisp. Todo lo que aparece en una línea despues de un punto y coma es un
   comentario. Se utilizan dos, tres, y cuatro punto y coma como marcadores de
   subsección y sección. (Consulta la Seccion @l{elisp.html#Comments<>Comentarios} en @e(El
   Manual de Referencia GNU Emacs Lisp), para más informacion sobre los comentarios.)

#    ..src > elisp
#      ;;;; The Help Key
#      ; Control-h is the help key;
#      ; after typing control-h, type a letter to
#      ; indicate the subject about which you want help.
#      ; For an explanation of the help facility,
#      ; type control-h two times in a row.
#    < src..
   ..src > elisp
     ;;;; La Tecla de Ayuda
     ; Control-h es la tecla de ayuda;
     ; después de escribir control-h, escribe una letra
     ; para indicar el asunto sobre el que quieres ayuda.
     ; Para una explicación de la propia ayuda,
     ; escribe control-h dos veces seguidas.
   < src..

#    Just remember: type @k{C-h} two times for help.
   Solo recuerda: escribe @k{C-h} dos veces para pedir ayudar.

#    ..src > elisp
#      ; To find out about any mode, type control-h m
#      ; while in that mode. For example, to find out
#      ; about mail mode, enter mail mode and then type
#      ; control-h m.
#    < src..
   ..src > elisp
     ; Para conocer cualquier modo, presiona control-h m
     ; mientras estés en ese modo. Por ejemplo, para conocer
     ; sobre del modo correo, ingresa al modo correo y luego
     ; presiona control-h m.
   < src..

#    ‘Mode help’, as I call this, is very helpful. Usually, it tells you all
#    you need to know.
   El ‘Modo ayuda’, como yo lo llamo, es muy útil. Usualmente, dice todo lo que
   se necesita saber.

#    Of course, you don't need to include comments like these in your
#    @f{.emacs} file. I included them in mine because I kept forgetting about
#    Mode help or the conventions for comments––but I was able to remember to
#    look here to remind myself.
   Por supuesto, no necesitas incluir comentarios como estos en tu fichero
   @f{.emacs}. Yo los incluí en el mío porque siempre me olvidaba del Modo ayuda
   o las convenciones para los comentarios––pero pude recordarlos recordármelo a mí
   mismo.

# ** Text and Auto Fill Mode
** Modos Text y Auto Fill

#    Now we come to the part that ‘turns on’ Text mode and Auto Fill mode.
   Ahora llegamos a la parte que ‘activa’ al modo Text y el modo Auto Fill.

#    ..src > elisp
#      ;;; Text mode and Auto Fill mode
#      ;; The next two lines put Emacs into Text mode
#      ;; and Auto Fill mode, and are for writers who
#      ;; want to start writing prose rather than code.
#      (setq-default major-mode 'text-mode)
#      (add-hook 'text-mode-hook 'turn-on-auto-fill)
#    < src..
   ..src > elisp
     ;;; Modo Text y modo Auto Fill
     ;; Las siguiente dos líneas ponen a en Emacs en modo Text
     ;; y en el modo Auto Fill, y son para escritores que
     ;; quieren empezar a escribir en prosa en lugar de código.
     (setq-default major-mode 'text-mode)
     (add-hook 'text-mode-hook 'turn-on-auto-fill)
   < src..

#    Here is the first part of this @f{.emacs} file that does something besides
#    remind a forgetful human!
   ¡Aquí está la primera parte de este fichero @f{.emacs} que hace algo
   ademas de ayudarle a recordar a un humano olvidado!

#    The first of the two lines in parentheses tells Emacs to turn on Text mode
#    when you find a file, @e{unless} that file should go into some other mode,
#    such as C mode.
   La primera de las dos líneas entre paréntesis le indican a Emacs que active el
   modo Text cuando se encuentra un fichero, @e{a menos que} ese fichero
   este en algún otro modo, por ejemplo, el modo C.

#    When Emacs reads a file, it looks at the extension to the file name, if
#    any.  (The extension is the part that comes after a @'{.}.)  If the file
#    ends with a @'{.c} or @'{.h} extension then Emacs turns on C mode. Also,
#    Emacs looks at first nonblank line of the file; if the line says @'{-*- C
#    -*-}, Emacs turns on C mode. Emacs possesses a list of extensions and
#    specifications that it uses automatically. In addition, Emacs looks near
#    the last page for a per-buffer, “local variables list”, if any.
   Cuando Emacs lee un fichero, examina la extensión del nombre del fichero. (La
   extensión es la parte que esta después de un @'{.}.) Si el fichero finaliza
   con una extensión @'{.c} o @'{.h} entonces Emacs activa el modo C. Ademas,
   Emacs examina la primer línea no en blanco del fichero; si la línea dice
   @'{-*- C -*-}, Emacs activa el modo C. Emacs posee una lista de extensiones y
   especificaciones que usa automáticamente. Además, Emacs busca cerca de la
   última página por buffer una “lista variables locales”, si la hay.

#    See Section @l{emacs.html#Choosing Modes<>How Major Modes are Chosen} and
#    @l{emacs.html#File Variables<>Local Variables in Files} in @e(The GNU Emacs
#    Manual).
   Consulta las secciones @l{emacs.html#Choosing Modes<>Cómo se Eligen
   los Modos Mayores} y @l{emacs.html#File Variables<>Variables Locales en Ficheros}
   en @e{El Manual de GNU Emacs}.

#    Now, back to the @f{.emacs} file.
   Ahora, volvamos al fichero @f{.emacs}.

#    Here is the line again; how does it work?
   Aquí está la línea de nuevo; ¿cómo funciona?

#    ..src > elisp
#      (setq major-mode 'text-mode)
#    < src..
   ..src > elisp
     (setq major-mode 'text-mode)
   < src..

#    This line is a short, but complete Emacs Lisp expression.
   Esta corta línea es una expresion Lisp.

#    We are already familiar with @c{setq}. It sets the following variable,
#    @c{major-mode}, to the subsequent value, which is @c{text-mode}. The
#    single quote mark before @c{text-mode} tells Emacs to deal directly with
#    the @c{text-mode} symbol, not with whatever it might stand for. See
#    Section @l{#Setting the Value of a Variable}, for a reminder of how
#    @c{setq} works. The main point is that there is no difference between the
#    procedure you use to set a value in your @f{.emacs} file and the procedure
#    you use anywhere else in Emacs.
   Ya estamos familiarizados con @c{setq}. Esto establece la siguiente variable,
   @c{major-mode}, al valor subsiguiente, que es @c{text-mode}. La comilla
   simple antes de @c{text-mode} le indica a Emacs que trate directamente con el
   símbolo @c(text-mode), no con lo que pueda significar. Consulta la Seccion
   @l{#Establecer el Valor de una Variable}, para recordar como funciona @c{setq}.
   El punto principal es que no hay diferencia entre el procedimiento
   que se usa utiliza para establecer un valor en tu fichero @f{.emacs} y el procedimiento
   que se usa en cualquier otro lugar de Emacs.

#    Here is the next line:
   Aquí está la siguiente línea:

#    ..src > elisp
#      (add-hook 'text-mode-hook 'turn-on-auto-fill)
#    < src..
   ..src > elisp
     (add-hook 'text-mode-hook 'turn-on-auto-fill)
   < src..

#    In this line, the @c{add-hook} command adds @c{turn-on-auto-fill} to the
#    variable.
   En esta línea, el comando @c{add-hook} añade @c{turn-on-auto-fill} a la
   variable.

#    @c{turn-on-auto-fill} is the name of a program, that, you guessed it!,
#    turns on Auto Fill mode.
   ¡@c{turn-on-auto-fill} es el nombre de un programa, que lo adivinaste!,
   activa el modo Auto Fill.

#    Every time Emacs turns on Text mode, Emacs runs the commands ‘hooked’ onto
#    Text mode. So every time Emacs turns on Text mode, Emacs also turns on
#    Auto Fill mode.
   Cada vez que Emacs activa el modo Text, Emacs ejecuta los comandos ‘hooked’
   @%i(conectados) al modo Text. Por lo tanto, cada vez que Emacs activa el
   modo Text, Emacs también activa el modo Auto Fill.

#    In brief, the first line causes Emacs to enter Text mode when you edit a
#    file, unless the file name extension, a first non-blank line, or local
#    variables to tell Emacs otherwise.
   En resumen, la primer línea hace que Emacs entre en modo Text cuando se
   edita un fichero, a menos que la extensión del nombre del fichero, una
   primer línea no en blanco o variables locales le indiquen lo contrario.

#    Text mode among other actions, sets the syntax table to work conveniently
#    for writers. In Text mode, Emacs considers an apostrophe as part of a
#    word like a letter; but Emacs does not consider a period or a space as
#    part of a word. Thus, @k{M-f} moves you over @'{it's}. On the other
#    hand, in C mode, @k{M-f} stops just after the @'{t} of @'{it's}.
   El modo Text entre otras acciones, establece la tabla de sintaxis para
   trabajar adecuadamente a los escritores. En el modo Text, Emacs considera un
   apóstrofe como parte de una palabra como una letra; pero Emacs no
   considera un punto o un espacio como parte de una palabra. De este modo,
   @k{M-f} se mueve a través de @'{d'Alcañiz}. Por otro lado, en el modo C,
   @k{M-f} se detiene justo despues de la @'{d} de @'{d'Alcañiz}.

#    The second line causes Emacs to turn on Auto Fill mode when it turns on
#    Text mode. In Auto Fill mode, Emacs automatically breaks a line that is
#    too wide and brings the excessively wide part of the line down to the next
#    line. Emacs breaks lines between words, not within them.
   La segunda línea hace que Emacs active el modo Auto Fill cuando cambia al
   modo Text. En el modo Auto Fill, Emacs rompe automáticamente una línea
   que es demasiado ancha y mueve la parte exedente a la siguiente línea. Emacs
   rompe las líneas entre palabras, no dentro de ellas.

#    When Auto Fill mode is turned off, lines continue to the right as you type
#    them. Depending on how you set the value of @c{truncate-lines}, the words
#    you type either disappear off the right side of the screen, or else are
#    shown, in a rather ugly and unreadable manner, as a continuation line on
#    the screen.
   Cuando el modo Auto Fill está desactivado, las líneas continúan hacia la
   derecha a medida que se escriben. Dependiendo de como se establece el valor de
   @c{truncate-lines}, las palabras que escribas desaparecen del lado
   derecho de la pantalla, o bien se mostraran, de una manera bastante fea e
   ilegible, como una línea continua en la pantalla.

#    In addition, in this part of my @f{.emacs} file, I tell the Emacs fill
#    commands to insert two spaces after a colon:
   Además, en esta parte de mi fichero @f{.emacs}, le digo a los comandos de
   relleno que inserten dos espacios después de dos puntos:

#    ..src > elisp
#      (setq colon-double-space t)
#    < src..
   ..src > elisp
     (setq colon-double-space t)
   < src..

# ** Mail Aliases
** Alias de correo

#    Here is a @c{setq} that ‘turns on’ mail aliases, along with more
#    reminders.
   Aquí hay un @c{setq} que ‘activa’ el alias de correo, junto con mas recordatorios.

#    ..src > elisp
#      ;;; Mail mode
#      ; To enter mail mode, type ‘C-x m’
#      ; To enter RMAIL (for reading mail),
#      ; type ‘M-x rmail’
#      (setq mail-aliases t)
#    < src..
   ..src > elisp
     ;;; Modo Correo
     ; Para entrar en el modo correo, presiona ‘C-x m’
     ; Para entrar en RMAIL (para leer el correo),
     ; presiona ‘M-x rmail’
     (setq mail-aliases t)
   < src..

#    This @c{setq} command sets the value of the variable @c{mail-aliases} to
#    @c{t}. Since @c{t} means true, the line says, in effect, “Yes, use mail
#    aliases.”
   Este comando @c{setq} asigna el valor de la variable @c{mail-aliases} a
   @c{t}. Ya que @c{t} significa verdadero, la línea dice, “Sí, usa
   alias de correo.”

#    Mail aliases are convenient short names for long email addresses or for
#    lists of email addresses. The file where you keep your ‘aliases’ is
#    @f{~/.mailrc}. You write an alias like this:
   Los alias de correo son nombres cortos convenientes para direcciones
   de correo largas o para listas de direcciones de correo. El fichero
   donde guardas tus ‘aliases’ es @f{~/.mailrc}. Se escribe un alias como
   este:

#    ..example >
#      alias geo george@foobar.wiz.edu
#    < example..
   ..example >
     alias geo george@foobar.wiz.edu
   < example..

#    When you write a message to George, address it to @'{geo}; the mailer will
#    automatically expand @'{geo} to the full address.
   Cuando escribas un mensaje a Jorge, envialo a la dirección @'{geo}; el correo
   automáticamente expandirá @'{geo} a la dirección completa.

# ** Indent Tabs Mode
** Modo Indent Tabs

#    By default, Emacs inserts tabs in place of multiple spaces when it formats
#    a region.  (For example, you might indent many lines of text all at once
#    with the @c{indent-region} command.)  Tabs look fine on a terminal or with
#    ordinary printing, but they produce badly indented output when you use
#    T@_(E)X or Texinfo since T@_(E)X ignores tabs.
   Por defecto, Emacs inserta tabulaciones en lugar en espacios múltiples
   cuando se da formato a una región. (Por ejemplo, se podrían indentar muchas
   líneas de texto a la vez con el comando @c{indent-region}.) Los
   tabuladores se ven bien en un terminal o con impresión ordinaria, pero
   producen una salida mal indentada cuando se usa T@_(E)X o Texinfo
   ya que T@_(E)X ignora los tabuladores.

#    The following turns off Indent Tabs mode:
   Lo siguiente desactiva el modo de Indent Tabs:

#    ..src > elisp
#      ;;; Prevent Extraneous Tabs
#      (setq-default indent-tabs-mode nil)
#    < src..
   ..src > elisp
     ;;; Prevenir Tabulaciones Extrañas
     (setq-default indent-tabs-mode nil)
   < src..

#    Note that this line uses @c{setq-default} rather than the @c{setq} command
#    that we have seen before. The @c{setq-default} command sets values only
#    in buffers that do not have their own local values for the variable.
   Observa que esta línea usa @c{setq-default} en vez de el comando @c{setq} que
   hemos visto antes. El comando @c{setq-default} asigna valores solo en
   búfers que no tienen sus propios valores locales para la variable.

#    See Section @l{emacs.html#Just Spaces<>Tabs vs. Spaces} and
#    @l{emacs.html#File Variables<>Local Variables in Files}
#    in @e(The GNU Emacs Manual).
   Consulta las secciones @l{emacs.html#Just Spaces<>Tabuladores versus Espacios} y
   @l{emacs.html#File Variables<>Variables Locales en Ficheros} en @e{El Manual
   de GNU Emacs}.

# ** Some Keybindings
** Algunos Atajos de teclado

#    Now for some personal keybindings:
   Ahora algunos atajos personales:

#    ..src > elisp
#      ;;; Compare windows
#      (global-set-key "\C-cw" 'compare-windows)
#    < src..
   ..src > elisp
     ;;; Compara ventanas
     (global-set-key "\C-cw" 'compare-windows)
   < src..

#    @c{compare-windows} is a nifty command that compares the text in your
#    current window with text in the next window. It makes the comparison by
#    starting at point in each window, moving over text in each window as far
#    as they match. I use this command all the time.
   @c{compare-windows} es un comando excelente que compara el texto de la
   ventana actual con el texto de la siguiente ventana. Realiza la comparación
   empezando en el punto en cada ventana, moviendose a través del texto en cada
   ventana en la medida en que coincidan. Uso este comando todo el tiempo.

#    This also shows how to set a key globally, for all modes.
   Esto también muestra como configurar una atajo globalmente, para todos los
   modos

#    The command is @c{global-set-key}. It is followed by the keybinding. In
#    a @f{.emacs} file, the keybinding is written as shown: @c{\C-c} stands for
#    ‘control-c’, which means ‘press the control key and the @k{c} key at the
#    same time’. The @c{w} means ‘press the @k{w} key’. The keybinding is
#    surrounded by double quotation marks. In documentation, you would write
#    this as @k{C-c w}.  (If you were binding a @k{META} key, such as @k{M-c},
#    rather than a @k{CTRL} key, you would write @c{\M-c} in your @f{.emacs}
#    file. See Section @l{emacs.html#Init Rebinding<>Rebinding Keys in Your
#    Init File} in @e(The GNU Emacs Manual), for details.)
   El comando es @c{global-set-key}. Va seguido por el atajo de teclado. En un fichero
   @f{.emacs}, el atajo se escribe como se muestrta: @c{\C-c} significa
   ‘control-c’, lo que significa ‘presionar la tecla de control y la tecla @k{c}
   al mismo tiempo’. La @c{w} significa ‘presionar la tecla @k{w}’. El atajo esta
   rodeado por comillas dobles. En el atajo, se presionaria esto como @k{C-c
   w}. (Si estuvieras enlazando una tecla @k{META}, como @k{M-c}, en lugar de la
   tecla @k{CTRL}, se escribiría @c{\M-c} en el fichero @f{.emacs}. Consulta la
   Seccion @l{emacs.html#Init Rebinding<>Teclas de atajos en tu fichero Init}
   en @e(El Manual de GNU Emacs), para más detalles.)

#    The command invoked by the keys is @c{compare-windows}. Note that
#    @c{compare-windows} is preceded by a single quote; otherwise, Emacs would
#    first try to evaluate the symbol to determine its value.
   El comando invocado por las teclas es @c{compare-windows}. Observa que
   @c{compare-windows} es precedido por una comilla simple; de otro modo,
   Emacs intentaría primero evaluar el símbolo para determinar su valor.

#    These three things, the double quotation marks, the backslash before the
#    @'{C}, and the single quote mark are necessary parts of keybinding that I
#    tend to forget. Fortunately, I have come to remember that I should look
#    at my existing @f{.emacs} file, and adapt what is there.
   Estas tres cosas, las comillas dobles, la barra invertida antes
   de la @'{C}, y la comilla simple son partes necesarias en los atajos
   de teclado que tiendo a olvidar. Afortunadamente, he llegado a recordarlo
   mirando mi fichero @f{.emacs}, y adaptando lo que hay alli.

#    As for the keybinding itself: @k{C-c w}. This combines the prefix key,
#    @k{C-c}, with a single character, in this case, @k{w}. This set of keys,
#    @k{C-c} followed by a single character, is strictly reserved for
#    individuals' own use.  (I call these ‘own’ keys, since these are for my
#    own use.)  You should always be able to create such a keybinding for your
#    own use without stomping on someone else's keybinding. If you ever write
#    an extension to Emacs, please avoid taking any of these keys for public
#    use. Create a key like @k{C-c C-w} instead. Otherwise, we will run out
#    of ‘own’ keys.
   En cuanto al atajo: @k{C-c w}, combina la tecla prefija, @k{C-c},
   con un caracter simple, en este caso, @k{w}. Este conjunto de teclas,
   @k{C-c} seguido por un solo caracter, esta estrictamente reservado para
   uso individual. (Llamo a estas teclas ‘propias’, ya que son
   para mi propio uso). Siempre debes ser capaz de crear un atajo de este tipo para
   tu propio uso sin pisar el atajo de otra persona. Si alguna vez escribes una
   extensión a Emacs, por favor, evita tomar cualquiera de estos atajos para
   uso público. Crea un combinacion @k{C-c C-w} en su lugar. De lo contrario,
   nos quedaremos sin atajos ‘propios’.

#    Here is another keybinding, with a comment:
   Aquí hay otro atajo, con un comentario:

#    ..src > elisp
#      ;;; Keybinding for ‘occur’
#      ; I use occur a lot, so let's bind it to a key:
#      (global-set-key "\C-co" 'occur)
#    < src..
   ..src > elisp
     ;;; Atajo para ‘occur’
     ; Uso mucho occur, así que voy a asignarlo a un atajo:
     (global-set-key "\C-co" 'occur)
   < src..

#    The @c{occur} command shows all the lines in the current buffer that
#    contain a match for a regular expression. Matching lines are shown in a
#    buffer called @f{*Occur*}. That buffer serves as a menu to jump to
#    occurrences.
   El comando @c{occur} muestra todas las líneas en el buffer actual que
   contiene una coincidencia para una expresión regular. Las líneas que
   coinciden se muestran en un búfer llamado @f{*Occur*}. Esse buffer sirve como
   un menu para saltar a las ocurrencias.

#    Here is how to unbind a key, so it does not work:
   Aquí se muestra como desasignar un atajo, para que no funcione:

#    ..src > elisp
#      ;;; Unbind ‘C-x f’
#      (global-unset-key "\C-xf")
#    < src..
   ..src > elisp
     ;;; Desasociar ‘C-x f’
     (global-unset-key "\C-xf")
   < src..

#    There is a reason for this unbinding: I found I inadvertently typed @k{C-x
#    f} when I meant to type @k{C-x C-f}. Rather than find a file, as I
#    intended, I accidentally set the width for filled text, almost always to a
#    width I did not want. Since I hardly ever reset my default width, I
#    simply unbound the key.
   Hay una razón para esto: Encuentro que inadvertidamente presiono @k{C-x f} en
   lugar de @k{C-x C-f}. En lugar de encontrar un fichero, como pretendia,
   accidentalmente asigno el ancho del modo Auto Fill, casi siempre a un
   tamaño que no quería. Como casi nunca reseteó mi ancho por defecto,
   simplemente desvinculo el atajo.

#    The following rebinds an existing key:
   Lo siguiente reasocia un atajo existente:

#    ..src > elisp
#      ;;; Rebind ‘C-x C-b’ for ‘buffer-menu’
#      (global-set-key "\C-x\C-b" 'buffer-menu)
#    < src..
   ..src > elisp
     ;;; Reasocia ‘C-x C-b’ a ‘buffer-menu’
     (global-set-key "\C-x\C-b" 'buffer-menu)
   < src..

#    By default, @k{C-x C-b} runs the @c{list-buffers} command. This command
#    lists your buffers in @e{another} window. Since I almost always want to
#    do something in that window, I prefer the @c{buffer-menu} command, which
#    not only lists the buffers, but moves point into that window.
   Por defecto, @k{C-x C-b} ejecuta el comando @c{list-buffers}. Este comando
   lista tus buffers en @e{otra} ventana. Como casi siempre quiero hacer algo en
   esa ventana, prefiero el comando @c{buffer-menu}, que no solo lista los
   buffers, sino que tambien mueve el punto a esa ventana.

# ** Keymaps
** Mapas de teclado

#    Emacs uses @:{keymaps} to record which keys call which commands. When you
#    use @c{global-set-key} to set the keybinding for a single command in all
#    parts of Emacs, you are specifying the keybinding in
#    @c{current-global-map}.
   Emacs usa @:{keymaps} para registrar qué teclas llaman a qué comandos. Cuando
   se usa @c{global-set-key} para asignar los atajos de teclado a un unico
   comando en todas las partes de Emacs, se esta especificando el atajo en el
   @c{current-global-map}.

#    Specific modes, such as C mode or Text mode, have their own keymaps; the
#    mode-specific keymaps override the global map that is shared by all
#    buffers.
   Los Modos específicos, como el modo C o el modo Texto, tiene sus propios
   mapas de teclado; los mapas de teclado específico del modo sobreescriben el
   mapa global que comparten todos los buffers.

#    The @c{global-set-key} function binds, or rebinds, the global keymap. For
#    example, the following binds the key @k{C-x C-b} to the function
#    @c{buffer-menu}:
   La función @c{global-set-key} asocia, o reasocia, el mapa de teclas
   global. Por ejemplo, lo siguiente vincula el atajo @k{C-x C-b} a la
   función @c{buffer-menu}:

#    ..src > elisp
#      (global-set-key "\C-x\C-b" 'buffer-menu)
#    < src..
   ..src > elisp
     (global-set-key "\C-x\C-b" 'buffer-menu)
   < src..

#    Mode-specific keymaps are bound using the @c{define-key} function, which
#    takes a specific keymap as an argument, as well as the key and the
#    command. For example, my @f{.emacs} file contains the following
#    expression to bind the @c{texinfo-insert-@@group} command to @k{C-c C-c
#    g}:
   Los Mapas de teclado específicos de un modo se vinculan mediente la función
   @c{define-key}, que toma un mapa de teclado específico como un argumento,
   asi como el atajo y el comando. Por ejemplo, mi fichero @f{.emacs}
   contiene la siguiente expresión para vincular el comando
   @c{texinfo-insert-@@group} a @k{C-c C-c g}:

#    ..src > elisp
#      (define-key texinfo-mode-map "\C-c\C-cg" 'texinfo-insert-@group)
#    < src..
   ..src > elisp
     (define-key texinfo-mode-map "\C-c\C-cg" 'texinfo-insert-@group)
   < src..

#    The @c{texinfo-insert-@@group} function itself is a little extension to
#    Texinfo mode that inserts @'{@@group} into a Texinfo file. I use this
#    command all the time and prefer to type the three strokes @k{C-c C-c g}
#    rather than the six strokes @k{@@ g r o u p}.  (@'{@@group} and its
#    matching @'{@@end group} are commands that keep all enclosed text together
#    on one page; many multi-line examples in this book are surrounded by
#    @'{@@group … @@end group}.)
   La función @c{texinfo-insert-@@group} en si misma es una pequeña extensión del
   modo Texinfo que inserta @'{@@group} dentro de un fichero Texinfo. Utilizo
   este comando todo el tiempo y prefiero escribir los tres atajos @k{C-c
   C-c g} en vez de los seis caracteres @k{@@ g r o u p}. (@'{@@group} y su
   acompañante @'{@@end group} son comandos que mantienen todo el texto que encierran
   en una página; muchos ejemplos multi-línea en este libro están
   rodeados por @'{@@group … @@end group}.)

#    Here is the @c{texinfo-insert-@@group} function definition:
   Aquí está la definición de la función @c{texinfo-insert-@@group}:

#    ..src > elisp
#      (defun texinfo-insert-@group ()
#        "Insert the string @group in a Texinfo buffer."
#        (interactive)
#        (beginning-of-line)
#        (insert "@group\n"))
#    < src..
   ..src > elisp
     (defun texinfo-insert-@group ()
       "Inserta la cadena @group en un búfer Texinfo."
       (interactive)
       (beginning-of-line)
       (insert "@group\n"))
   < src..

#    (Of course, I could have used Abbrev mode to save typing, rather than
#    write a function to insert a word; but I prefer key strokes consistent
#    with other Texinfo mode key bindings.)
   (Por supuesto, podría haber usado el modo Abbrev para evitar la fatiga de
   escribir, en vez de crear una función para insertar una palabra; pero
   prefiero tener atajos de teclado coherentes con otros atajos del modo Texinfo.)

#    You will see numerous @c{define-key} expressions in @f{loaddefs.el} as
#    well as in the various mode libraries, such as @f{cc-mode.el} and
#    @f{lisp-mode.el}.
   Verás numerosas expresiones @c{define-key} en @f{loaddefs.el} asi como en las
   diversas librerias de los modos, como @f{cc-mode.el} y @f{lisp-mode.el}.

#    See Section @l{emacs.html#Key Bindings<>Customizing Key Bindings} in
#    @e(The GNU Emacs Manual), and Section @l{elisp.html#Keymaps<>Keymaps} in
#    @e{The GNU Emacs Lisp Reference Manual}, for more information about
#    keymaps.
   Para más información sobre los mapas de teclado, consulta la Seccion
   @l{emacs.html#Key Bindings<>Personalizando Atajos de Teclado} en @e(El Manual
   de GNU Emacs), y la Seccion @l{elisp.html#Keymaps<>Mapas de Teclado} en @e(El
   Manual de Referencia de GNU Emacs Lisp).

# ** Loading Files
** Cargando ficheros

#    Many people in the GNU Emacs community have written extensions to Emacs.
#    As time goes by, these extensions are often included in new releases. For
#    example, the Calendar and Diary packages are now part of the standard GNU
#    Emacs, as is Calc.
   Muchas personas en la comunidad de GNU Emacs han escrito extensiones para
   Emacs. Con el paso del tiempo, estas extensiones a menudo se incluiyen en
   las nuevas versiones. Por ejemplo, los paquetes Calendar y
   Diary son ahora parte del GNU Emacs estándar, como lo es Calc.

#    You can use a @c{load} command to evaluate a complete file and thereby
#    install all the functions and variables in the file into Emacs. For
#    example:
   Se puede usar el comando @c{load} para evaluar un fichero completo y, por lo
   tanto, instalar todas las funciones y variables del fichero en Emacs. Por
   ejemplo:

#    ..src > elisp
#      (load "~/emacs/slowsplit")
#    < src..
   ..src > elisp
     (load "~/emacs/slowsplit")
   < src..

#    This evaluates, i.e., loads, the @f{slowsplit.el} file or if it exists,
#    the faster, byte compiled @f{slowsplit.elc} file from the @f{emacs}
#    sub-directory of your home directory. The file contains the function
#    @c{split-window-quietly}, which John Robinson wrote in 1989.
   Esto evalúa, es decir, carga, el fichero @f{slowsplit.el} o si existe,
   el fichero compilado mas rapido @f{slowsplit.elc}, desde el
   subdirectorio @f{emacs} en tu directorio home. El fichero contiene la
   función @c{split-window-quietly}, que John Robinson escribió en 1989.

#    The @c{split-window-quietly} function splits a window with the minimum of
#    redisplay. I installed it in 1989 because it worked well with the slow
#    1200 baud terminals I was then using. Nowadays, I only occasionally come
#    across such a slow connection, but I continue to use the function because
#    I like the way it leaves the bottom half of a buffer in the lower of the
#    new windows and the top half in the upper window.
   La función @c{split-window-quietly} divide una ventana con el mínimo de
   redisplay. La instalé en 1989 porque funcionaba bien con los viejos
   terminales de 1200 baudios que usaba entonces. Hoy en dia, solo de vez en
   cuando me encuentro con una conexión tan lenta, pero sigo usando la función
   porque me gusta la forma en que deja la mitad inferior de un búfer en la
   parte inferior de la nueva ventana y la mitad superior en la ventana superior.

#    To replace the key binding for the default @c{split-window-vertically},
#    you must also unset that key and bind the keys to
#    @c{split-window-quietly}, like this:
   Para reemplazar el atajo de teclado por defecto de
   @c{split-window-vertically}, se debe desactivar ese atajo y
   asociarlo de nuevo a @c{split-window-quietly}, asi:

#    ..src > elisp
#      (global-unset-key "\C-x2")
#      (global-set-key "\C-x2" 'split-window-quietly)
#    < src..
   ..src > elisp
     (global-unset-key "\C-x2")
     (global-set-key "\C-x2" 'split-window-quietly)
   < src..

#    If you load many extensions, as I do, then instead of specifying the exact
#    location of the extension file, as shown above, you can specify that
#    directory as part of Emacs's @c{load-path}. Then, when Emacs loads a
#    file, it will search that directory as well as its default list of
#    directories.  (The default list is specified in @f{paths.h} when Emacs is
#    built.)
   Si cargas muchas extensiones, como yo, entonces en lugar de
   especificar la ubicacion exacta del fichero de extencion, como se muestra arriba, se
   puede especificar el directorio como la funcion @c{load-path} de
   Emacs. En ese caso, cuando Emacs carga un fichero, buscará en ese directorio asi
   como en la lista predeterminada de directorios. (La lista predeterminada se
   especificada en @f{paths.h} cuando se construye Emacs.)

#    The following command adds your @f{~/emacs} directory to the existing load
#    path:
   El siguiente comando añade tu directorio @f{~/emacs} a la ruta de carga existente:

#    ..src > elisp
#      ;;; Emacs Load Path
#      (setq load-path (cons "~/emacs" load-path))
#    < src..
   ..src > elisp
     ;;; Ruta de carga Emacs
     (setq load-path (cons "~/emacs" load-path))
   < src..

#    Incidentally, @c{load-library} is an interactive interface to the @c{load}
#    function. The complete function looks like this:
   Por cierto, @c{load-library} es una interfaz interactiva para la función
   @c{load}. La función tiene el siguiente aspecto:

#    ..src > elisp
#      (defun load-library (library)
#        "Load the library named LIBRARY.
#      This is an interface to the function ‘load’."
#        (interactive
#         (list (completing-read "Load library: "
#                                (apply-partially 'locate-file-completion-table
#                                                 load-path
#                                                 (get-load-suffixes)))))
#        (load library))
#    < src..
   ..src > elisp
     (defun load-library (library)
       "Carga la librería llamada LIBRARY.
     Esta es una interfaz para la función ‘load’."
       (interactive
        (list (completing-read "Carga la librería: "
                               (apply-partially 'locate-file-completion-table
                                                load-path
                                                (get-load-suffixes)))))
       (load library))
   < src..

#    The name of the function, @c{load-library}, comes from the use of
#    ‘library’ as a conventional synonym for ‘file’. The source for the
#    @c{load-library} command is in the @f{files.el} library.
   El nombre de la función, @c{load-libray}, proviene del uso de ‘library’
   como un sinónimo convencional de ‘fichero’. El codigo del comando @c{load-library}
   está en la librería @f{files.el}.

#    Another interactive command that does a slightly different job is
#    @c{load-file}. See Section @l{emacs.html#Lisp Libraries<>Libraries of
#    Lisp Code for Emacs} in @e(The GNU Emacs Manual), for information on the
#    distinction between @c{load-library} and this command.
   Otro comando interactivo que hace un trabajo ligeramente diferente es
   @c{load-file}. Consulta la Seccion @l{emacs.html#Lisp Libraries<>Librerías de
   Código Lisp para Emacs} en @e(El Manual de GNU Emacs), para obtener
   información sobre la diferencia entre @c{load-library} y este comando.

# ** Autoloading
** Autocarga

#    Instead of installing a function by loading the file that contains it, or
#    by evaluating the function definition, you can make the function available
#    but not actually install it until it is first called. This is called
#    @:{autoloading}.
   En lugar de instalar una función cargando el fichero que la contiene, o
   evaluando la definición de función, puedes hacer que la función este disponible
   pero no instalarla hasta que se llame por primera vez. Este proceso
   se llama @:{autocarga}.

#    When you execute an autoloaded function, Emacs automatically evaluates the
#    file that contains the definition, and then calls the function.
   Cuando se ejecuta una función de autocarga, Emacs evalúa automáticamente
   el fichero que contiene la definición, y entonces llama a la función.

#    Emacs starts quicker with autoloaded functions, since their libraries are
#    not loaded right away; but you need to wait a moment when you first use
#    such a function, while its containing file is evaluated.
   Emacs inicia mas rápido con funciones de autocarga, ya que sus librerías no
   se cargan de inmediato; pero es necesario esperar un momento cuando se
   utiliza por primera vez una función de este tipo, mientras se evalua el
   fichero que la contiene.

#    Rarely used functions are frequently autoloaded. The @f{loaddefs.el}
#    library contains hundreds of autoloaded functions, from @c{bookmark-set}
#    to @c{wordstar-mode}. Of course, you may come to use a ‘rare’ function
#    frequently. When you do, you should load that function's file with a
#    @c{load} expression in your @f{.emacs} file.
   Las funciones poco utilizadas con frecuencia se autocargan. La librería
   @f{loaddefs.el} coniene cientos de funciones autocargadas, desde el modo
   @c{bookmark-set} hasta el modo @c{wordstar-mode}. Por supuesto, puedes
   llegar a utilizar una función ‘rara’ con frecuencia, cuando sea asi deberías
   cargar ese fichero de función con una expresión @c{load} en tu fichero
   @f{.emacs}.

#    In my @f{.emacs} file, I load 14 libraries that contain functions that
#    would otherwise be autoloaded.  (Actually, it would have been better to
#    include these files in my ‘dumped’ Emacs, but I forgot. See Section
#    @l{elisp.html#Building Emacs<>Building Emacs} in @e{The GNU Emacs Lisp
#    Reference Manual}, and the @f{INSTALL} file for more about dumping.)
   En mi fichero @f{.emacs}, cargo 14 librerías que contienen funciones que de
   otro modo serían autocargadas. (En realidad, hubiera sido mejor incluir estos
   ficheros en mi Emacs ‘volcado’, pero lo olvide. Consulta la Sección
   @l{elisp.html#Building Emacs<>Construyendo Emacs} en @e(El Manual de
   Referencia de GNU Emacs Lisp), y el fichero @f{INSTALL} para más informacion
   acerca del volcado.)

#    You may also want to include autoloaded expressions in your @f{.emacs}
#    file.  @c{autoload} is a built-in function that takes up to five
#    arguments, the final three of which are optional. The first argument is
#    the name of the function to be autoloaded; the second is the name of the
#    file to be loaded. The third argument is documentation for the function,
#    and the fourth tells whether the function can be called interactively.
#    The fifth argument tells what type of object––@c{autoload} can handle a
#    keymap or macro as well as a function (the default is a function).
   Tambien puedes querer incluir expresiones de autocarga en tu fichero
   @f{.emacs}. @c{autoload} es una función nativa que toma hasta cinco
   argumentos, los tres ultimos son opcionales. El primer argumento es el nombre
   de la función para autocargar. El segundo es el nombre del fichero a cargar.
   El tercer argumento es la documentación de la función, y el cuarto dice si la
   función puede llamarse de forma interactiva. El quinto argumento es el tipo
   de objeto––@c{autoload} puede manejar un mapa de teclado o macro asi como una
   función (el valor por defecto es una función).

#    Here is a typical example:
   Aquí hay un ejemplo típico:

#    ..src > elisp
#      (autoload 'html-helper-mode
#        "html-helper-mode" "Edit HTML documents" t)
#    < src..
   ..src > elisp
     (autoload 'html-helper-mode
       "html-helper-mode" "Editar documentos HTML" t)
   < src..

#    (@c{html-helper-mode} is an older alternative to @c{html-mode}, which is a
#    standard part of the distribution.)
   (@c{html-helper-mode} es una alternativa mas antigua a @c{html-mode}, que es una
   parte estándar de la distribución.)

#    This expression autoloads the @c{html-helper-mode} function. It takes it
#    from the @f{html-helper-mode.el} file (or from the byte compiled version
#    @f{html-helper-mode.elc}, if that exists.)  The file must be located in a
#    directory specified by @c{load-path}. The documentation says that this is
#    a mode to help you edit documents written in the HyperText Markup
#    Language. You can call this mode interactively by typing @k{M-x
#    html-helper-mode}.  (You need to duplicate the function's regular
#    documentation in the autoload expression because the regular function is
#    not yet loaded, so its documentation is not available.)
   Esta expresión autocarga la función @c{html-helper-mode}. Se toma
   del fichero @f{html-helper-mode-el} (o desde la versión compilada
   @f{html-helper-mode.elc}, si existe). El fichero debe estar ubicado
   en un directorio específicado por @c{load-path}. La documentación dice que
   este es un modo para ayudar a editar documentos escritos en Lenguaje de
   Marcas de Hiper Texto. Puedes llamar a este modo interactivamente
   escribiendo @k{M-x html-helper-mode}. (Se necesita duplicar la documentacion de
   la funcion regular en la expresión de autocarga porque la función
   regular todavia no está cargada, así que su documentación no está disponible.)

#    See Section @l{elisp.html#Autoload<>Autoload} in @e{The GNU Emacs Lisp
#    Reference Manual}, for more information.
   Consulta la Seccion @l{elisp.html#Autoload<>Autocarga} en @e(El Manual de
   Referencia de GNU Emacs Lisp), para más información.

# ** A Simple Extension: @c{line-to-top-of-window}
** Una extensión simple: @c{linea-a-lo-alto-de-la-ventana}

#    Here is a simple extension to Emacs that moves the line point is on to the
#    top of the window. I use this all the time, to make text easier to read.
   Aquí esta una extensión simple para Emacs que mueve linea donde esta el punto a la
   parte superior de la ventana. Uso esto todo el tiempo, para hacer que el
   texto sea mas fácil de leer.

#    You can put the following code into a separate file and then load it from
#    your @f{.emacs} file, or you can include it within your @f{.emacs} file.
   Puedes poner el siguiente código dentro de un fichero separado y luego
   cargarlo desde tu fichero @f{.emacs}, o tambien incluirlo en tu fichero
   @f{.emacs}.

#    Here is the definition:
   Aquí está la definición

#    ..src > elisp
#      ;;; Line to top of window;
#      ;;; replace three keystroke sequence  C-u 0 C-l
#      (defun line-to-top-of-window ()
#        "Move the line point is on to top of window."
#        (interactive)
#        (recenter 0))
#    < src..
   ..src > elisp
     ;;; Línea a lo alto de la ventana;
     ;;; Reemplaza tres pulsaciones de teclado C-u 0 C-l
     (defun linea-a-lo-alto-de-la-ventana ()
       "Mueve la línea donde esta el punto a lo alto de la ventana."
       (interactive)
       (recenter 0))
   < src..

#    Now for the keybinding.
   Ahora para el atajo.

#    Nowadays, function keys as well as mouse button events and non-@c{ascii}
#    characters are written within square brackets, without quotation marks.
#    (In Emacs version 18 and before, you had to write different function key
#    bindings for each different make of terminal.)
   Hoy en día, las teclas de función, así como los eventos del ratón y los
   caracteres no @c{ascii} se escriben entre corchetes, sin comillas. (En la
   versión 18 de Emacs y anteriores, se tenían que escribir diferentes
   combinaciones de teclas de función para cada terminal.)

#    I bind @c{line-to-top-of-window} to my @k{F6} function key like this:
   Vincule @c{linea-a-lo-alto-de-la-ventana} con mi tecla de función @k{F6}
   así:

#    ..src > elisp
#      (global-set-key [f6] 'line-to-top-of-window)
#    < src..
   ..src > elisp
     (global-set-key [f6] 'linea-a-lo-alto-de-la-ventana)
   < src..

#    For more information, see Section @l{emacs.html#Init Rebinding<>Rebinding
#    Keys in Your Init File} in @e(The GNU Emacs Manual).
   Para más información, consulta la Seccion @l{emacs.html#Init Rebinding<>Reasociando Teclas
   en tu fichero init} en @e{El Manual de GNU Emacs}.

#    If you run two versions of GNU Emacs, such as versions 22 and 23, and use
#    one @f{.emacs} file, you can select which code to evaluate with the
#    following conditional:
   Si ejecutas dos versiones de GNU Emacs, como las versiones 22 y 23, y
   usas un fichero @f{.emacs}, puedes seleccionar qué código evalúar con el
   siguiente condicional:

#    ..src > elisp
#      (cond
#       ((= 22 emacs-major-version)
#        ;; evaluate version 22 code
#        ( … ))
#       ((= 23 emacs-major-version)
#        ;; evaluate version 23 code
#        ( … )))
#    < src..
   ..src > elisp
     (cond
      ((= 22 emacs-major-version)
       ;; evalúa el codigo de la version 22
       ( … ))
      ((= 23 emacs-major-version)
       ;; evalúa el codigo de la version 23
       ( … )))
   < src..

#    For example, recent versions blink their cursors by default. I hate such
#    blinking, as well as other features, so I placed the following in my
#    @f{.emacs} file@n{15}:
   Por ejemplo, en las versiones recientes el cursor parpadea por defecto. Odio
   este tipo de parpadeo, como tambien otras caracteristicas, asi que puse lo
   siguiente en mi fichero @f{.emacs}@n{15}:

#    ..src > elisp
#      (when (>= emacs-major-version 21)
#        (blink-cursor-mode 0)
#        ;; Insert newline when you press ‘C-n’ (next-line)
#        ;; at the end of the buffer
#        (setq next-line-add-newlines t)
#        ;; Turn on image viewing
#        (auto-image-file-mode t)
#        ;; Turn on menu bar (this bar has text)
#        ;; (Use numeric argument to turn on)
#        (menu-bar-mode 1)
#        ;; Turn off tool bar (this bar has icons)
#        ;; (Use numeric argument to turn on)
#        (tool-bar-mode nil)
#        ;; Turn off tooltip mode for tool bar
#        ;; (This mode causes icon explanations to pop up)
#        ;; (Use numeric argument to turn on)
#        (tooltip-mode nil)
#        ;; If tooltips turned on, make tips appear promptly
#        (setq tooltip-delay 0.1)  ; default is 0.7 second
#         )
#    < src..
   ..src > elisp
     (when (>= emacs-major-version 21)
       (blink-cursor-mode 0)
       ;; Insertar una nueva línea cuando se presiona ‘C-n’ (next-line)
       ;; al fin del búfer
       (setq next-line-add-newlines t)
       ;; Activar la visualizacion de imagenes
       (auto-image-file-mode t)
       ;; Activa la barra de menu (esta barra tiene texto)
       ;; (Usa un argumento numérico para activarlo)
       (menu-bar-mode 1)
        ;; Desactivar la barra de herramientas (esta barra tiene iconos)
        ;; (Usa un argumento numérico para activarlo)
        (tool-bar-mode nil)
       ;; Desactiva el modo de informacion sobre la barra de herramientas
       ;; (Este modo hace que aparezcan explicaciones emergentes en los iconos)
       ;; (Usa un argumento numérico para activarlo)
       (tooltip-mode nil)
       ;; Si las sugerencias estan activadas, hace que aparezcan rapidamente
       (setq tooltip-delay 0.1)  ; por defecto es 0.7 segundos
        )
   < src..

# ** X11 Colors
** Colores X11

#    You can specify colors when you use Emacs with the MIT X Windowing system.
   Se pueden especificar colores cuando se usa Emacs con el Sistema de
   Ventanas X del MIT.

#    I dislike the default colors and specify my own.
   No me gustan los colores por defecto y especifico los mios propios.

#    Here are the expressions in my @f{.emacs} file that set values:
   Aquí están las expresiones en mi fichero @f{.emacs} que establecen los valores:

#    ..src > elisp
   ..src > elisp
#      ;; Set cursor color
#      (set-cursor-color "white")
     ;; Asigna el color del cursor
     (set-cursor-color "white")

#      ;; Set mouse color
#      (set-mouse-color "white")
     ;; Asigna el color del ratón
     (set-mouse-color "white")

#      ;; Set foreground and background
#      (set-foreground-color "white")
#      (set-background-color "darkblue")
     ;; Asigna el color del texto y del fondo
     (set-foreground-color "white")
     (set-background-color "darkblue")

#      ;;; Set highlighting colors for isearch and drag
#      (set-face-foreground 'highlight "white")
#      (set-face-background 'highlight "blue")
     ;;; Asigna colores para el resaltado de busqueda y registros
     (set-face-foreground 'highlight "white")
     (set-face-background 'highlight "blue")

#      (set-face-foreground 'region "cyan")
#      (set-face-background 'region "blue")
     (set-face-foreground 'region "cyan")
     (set-face-background 'region "blue")

#      (set-face-foreground 'secondary-selection "skyblue")
#      (set-face-background 'secondary-selection "darkblue")
     (set-face-foreground 'secondary-selection "skyblue")
     (set-face-background 'secondary-selection "darkblue")

#      ;; Set calendar highlighting colors
     ;; Asigna colores al calendario
#      (setq calendar-load-hook
#            (lambda ()
#              (set-face-foreground 'diary-face   "skyblue")
#              (set-face-background 'holiday-face "slate blue")
#              (set-face-foreground 'holiday-face "white")))
     (setq calendar-load-hook
           '(lambda ()
              (set-face-foreground 'diary-face   "skyblue")
              (set-face-background 'holiday-face "slate blue")
              (set-face-foreground 'holiday-face "white")))
#    < src..
   < src..

#    The various shades of blue soothe my eye and prevent me from seeing the
#    screen flicker.
   Las diferentes tonalidades de azul me alivian la vista y me impiden ver el
   parpadeo de la pantalla.

#    Alternatively, I could have set my specifications in various X
#    initialization files. For example, I could set the foreground,
#    background, cursor, and pointer (i.e., mouse) colors in my
#    @f{~/.Xresources} file like this:
   Alternativamente, podría haber establecido mis especificaciones en
   varios ficheros de inicialización X. Por ejemplo, podría establecer los
   colores del primer plano, fondo, cursor y puntero (es decir, ratón) en mi
   fichero @f{~/.Xresources} de esta manera:

#    ..example >
#      Emacs*foreground:   white
#      Emacs*background:   darkblue
#      Emacs*cursorColor:  white
#      Emacs*pointerColor: white
#    < example..
   ..example >
     Emacs*foreground:   white
     Emacs*background:   darkblue
     Emacs*cursorColor:  white
     Emacs*pointerColor: white
   < example..

#    In any event, since it is not part of Emacs, I set the root color of my X
#    window in my @f{~/.xinitrc} file, like this@n{16}:
   En cualquier caso, como no forma parte de Emacs, asigno el color raíz de
   mi ventana X en mi fichero @f{~/.xinitrc}, asi@n{16}

#    ..src > sh
#      xsetroot -solid Navy -fg white &
#    < src..
   ..src > sh
     xsetroot -solid Navy -fg white &
   < src..

# ** Miscellaneous Settings for a @f{.emacs} File
** Ajustes misceláneos para un fichero @f{.emacs}

#    Here are a few miscellaneous settings:
   Aquí hay algunos ajustes misceláneas:

#    - Set the shape and color of the mouse cursor:
   - Asigna la forma y color del cursor del ratón:

#      ..src > elisp
     ..src > elisp
#        ; Cursor shapes are defined in
#        ; ‘/usr/include/X11/cursorfont.h’;
#        ; for example, the ‘target’ cursor is number 128;
#        ; the ‘top_left_arrow’ cursor is number 132.
       ; Las formas de los cursores se definen en
       ; ‘/usr/include/X11/cursorfont.h’;
       ; por ejemplo, el cursor ‘objetivo’ es el número 128;
       ; el cursor ‘top_left_arrow’ es el número 132.

#        (let ((mpointer (x-get-resource "*mpointer"
#                                        "*emacs*mpointer")))
       (let ((mpointer (x-get-resource "*mpointer"
                                       "*emacs*mpointer")))
#          ;; If you have not set your mouse pointer
#          ;;     then set it, otherwise leave as is:
         ;; Si no has configurado el puntero del ratón
         ;; configuralo, de lo contrario, dejalo como esta:
#          (if (eq mpointer nil)
#              (setq mpointer "132")) ; top_left_arrow
#          (setq x-pointer-shape (string-to-int mpointer))
#          (set-mouse-color "white"))
         (if (eq mpointer nil)
             (setq mpointer "132")) ; top_left_arrow
         (setq x-pointer-shape (string-to-int mpointer))
         (set-mouse-color "white"))
#      < src..
     < src..

#    - Or you can set the values of a variety of features in an alist, like
#      this:
   - O se pueden asignar los valores de una variedad de caracteristicas en
     una lista, como esta:

#      ..src > elisp
#        (setq-default
#         default-frame-alist
#         '((cursor-color . "white")
#           (mouse-color . "white")
#           (foreground-color . "white")
#           (background-color . "DodgerBlue4")
#           ;; (cursor-type . bar)
#           (cursor-type . box)
#           (tool-bar-lines . 0)
#           (menu-bar-lines . 1)
#           (width . 80)
#           (height . 58)
#           (font . "-Misc-Fixed-Medium-R-Normal--20-200-75-75-C-100-ISO8859-1")
#           ))
#      < src..
     ..src > elisp
       (setq-default
        default-frame-alist
        '((cursor-color . "white")
          (mouse-color . "white")
          (foreground-color . "white")
          (background-color . "DodgerBlue4")
          ;; (cursor-type . bar)
          (cursor-type . box)
          (tool-bar-lines . 0)
          (menu-bar-lines . 1)
          (width . 80)
          (height . 58)
          (font . "-Misc-Fixed-Medium-R-Normal--20-200-75-75-C-100-ISO8859-1")
          ))
     < src..

#    - Convert @k{CTRL-h} into @k{DEL} and @k{DEL} into @k{CTRL-h}.
   - Convierte @k{CTRL-h} en @k{DEL} y @k{DEL} en @k{CTRL-h}.

#      (Some older keyboards needed this, although I have not seen the problem
#      recently.)
     (Algunos teclados viejos necesitan esto, aunque no he visto el problema
     recientemente.)

#      ..src > elisp
     ..src > elisp
#        ;; Translate ‘C-h’ to <DEL>.
#        ; (keyboard-translate ?\C-h ?\C-?)
       ;; Traducir ‘C-h’ a <DEL>.
       ; (keyboard-translate ?\C-h ?\C-?)

#        ;; Translate <DEL> to ‘C-h’.
#        (keyboard-translate ?\C-? ?\C-h)
       ;; Traducir <DEL> a ‘C-h’.
       (keyboard-translate ?\C-? ?\C-h)
#      < src..
     < src..

#    - Turn off a blinking cursor!
   - ¡Desactiva el parpadeo del cursor!

#      ..src > elisp
#        (if (fboundp 'blink-cursor-mode)
#            (blink-cursor-mode -1))
#      < src..
     ..src > elisp
       (if (fboundp 'blink-cursor-mode)
           (blink-cursor-mode -1))
     < src..

#      or start GNU Emacs with the command @${emacs -nbc}.
     o inicia GNU Emacs con el comando @${emacs -nbc}.

#    - When using @$(grep)
   - Cuando se utiliza @$(grep)

#      - @'c{-i}: Ignore case distinctions
     - @'c{-i}: Ignorar mayusculas o minusculas

#      - @'c{-n}: Prefix each line of output with line number
     - @'c{-n}: Prefija cada línea de la salida con el número de línea

#      - @'c{-H}: Print the filename for each match.
     - @'c{-H}: Imprime el nombre del fichero para cada coincidencia.

#      - @'c{-e}: Protect patterns beginning with a hyphen character, @'c{-}
     - @'c{-e}: Protege los patrones que empiezan con un guión, @'c{-}

#      ..src > elisp
#        (setq grep-command "grep -i -nH -e ")
#      < src..
       ..src > elisp
         (setq grep-command "grep -i -nH -e ")
       < src..

#    - Find an existing buffer, even if it has a different name
   - Encuentra un búfer existente, incluso si tiene un nombre diferente

#      This avoids problems with symbolic links.
     Esto evita problemas con los enlaces simbólicos.

#      ..src > elisp
#        (setq find-file-existing-other-name t)
#      < src..
     ..src > elisp
       (setq find-file-existing-other-name t)
     < src..

#    - Set your language environment and default input method
   - Establece el idioma del entorno y el método de entrada por defecto

#      ..src > elisp
#        (set-language-environment "latin-1")
#        ;; Remember you can enable or disable multilingual text input
#        ;; with the @c{toggle-input-method} (C-\) command
#        (setq default-input-method "latin-1-prefix")
#      < src..
     ..src > elisp
       (set-language-environment "latin-1")
       ;; Recuerda que se puede habilitar o deshabilitar la entrada de texto
       ;; multilingüe con el comando @c{toggle-input-method} (C-\)
       (setq default-input-method "latin-1-prefix")
     < src..

#      If you want to write with Chinese ‘GB’ characters, set this instead:
     Si quieres escribir con caracteres Chinos ‘GB’, asigna esto:

#      ..src > elisp
#        (set-language-environment "Chinese-GB")
#        (setq default-input-method "chinese-tonepy")
#      < src..
     ..src > elisp
       (set-language-environment "Chinese-GB")
       (setq default-input-method "chinese-tonepy")
     < src..

# *** Fixing Unpleasant Key Bindings
*** Corrigiendo Atajos de Teclados desagradables

#     Some systems bind keys unpleasantly. Sometimes, for example, the
#     @k{CTRL} key appears in an awkward spot rather than at the far left of
#     the home row.
    Algunos sistemas vinculan las teclas de forma desagradable. Algunas veces,
    por ejemplo, la tecla @k{CTRL} aparece en un lugar incomodo en lugar de en
    el extremo izquierdo de la fila de inicio.

#     Usually, when people fix these sorts of keybindings, they do not change
#     their @f{~/.emacs} file. Instead, they bind the proper keys on their
#     consoles with the @${loadkeys} or @${install-keymap} commands in their
#     boot script and then include @${xmodmap} commands in their @f{.xinitrc}
#     or @f{.Xsession} file for X Windows.
    Normalmente, cuando las gente arregla este tipo de atajos, no
    cambia su fichero @f{~/.emacs}. En su lugar, enlazan asocian las teclas
    apropiadas en la consola con los comandos @${loadkeys} o
    @${install-keymap} en su script de inicio e incluyen comandos
    @${xmodmap} en su fichero @f{.xinitrc} o @f{.Xsession} de X Windows.

#     For a boot script:
    Para un script de inicio:

#     ..src > sh
#       loadkeys /usr/share/keymaps/i386/qwerty/emacs2.kmap.gz
#     < src..
    ..src > sh
      loadkeys /usr/share/keymaps/i386/qwerty/emacs2.kmap.gz
    < src..

#     or
    o

#     ..src > sh
#       install-keymap emacs2
#     < src..
    ..src > sh
      install-keymap emacs2
    < src..

#     For a @f{.xinitrc} or @f{.Xsession} file when the @k{Caps Lock} key is at
#     the far left of the home row:
    Para un fichero @f{.xinitrc} o un fichero @f{.Xsession} cuando la tecla
    @k{Bloq Mayus} esta en el extremo izquierdo de la fila de inicio:

#     ..src > sh
    ..src > sh
#       # Bind the key labeled ‘Caps Lock’ to ‘Control’
#       # (Such a broken user interface suggests that keyboard manufacturers
#       # think that computers are typewriters from 1885.)
      # Asocia la tecla ‘Bloq Mayus’ a ‘Control’
      # (Una interfaz de usuario tan rota, sugiere que los fabricantes de teclados
      # piensan que las computadoras son máquinas de escribir de 1885.)

#       xmodmap -e "clear Lock"
#       xmodmap -e "add Control = Caps_Lock"
      xmodmap -e "clear Lock"
      xmodmap -e "add Control = Caps_Lock"
#     < src..
    < src..

#     In a @f{.xinitrc} or @f{.Xsession} file, to convert an @k{ALT} key to a
#     @k{META} key:
    En un fichero @f{.xinitrc} o @f{.Xsession}, para convertir una tecla @k{ALT} en
    una tecla @k{META}:

#     ..src > sh
#       # Some ill designed keyboards have a key labeled ALT and no Meta
#       xmodmap -e "keysym Alt_L = Meta_L Alt_L"
#     < src..
    ..src > sh
      # Algunos teclados mal diseñados tienen una tecla etiquetada ALT y no Meta
      xmodmap -e "keysym Alt_L = Meta_L Alt_L"
    < src..

# ** A Modified Mode Line
** Una línea de Modo modificada

#    Finally, a feature I really like: a modified mode line.
   Finalmente, una caracteristica que realmente me gusta: una linea de modo
   modificada.

#    When I work over a network, I forget which machine I am using. Also, I
#    tend to I lose track of where I am, and which line point is on.
   Cuando trabajo a través de una red, olvido que máquina estoy usando.
   También, tiendo a perder la nocion de donde estoy, y en que linea esta el punto.

#    So I reset my mode line to look like this:
   Así se restableci mi linea de modo para que se viera asi:

#    ..example >
#      ::-- foo.texi   rattlesnake:/home/bob/  Line 1  (Texinfo Fill) Top
#    < example..
   ..example >
     ::-- foo.texi   rattlesnake:/home/bob/  Line 1  (Texinfo Fill) Top
   < example..

#    I am visiting a file called @f{foo.texi}, on my machine @f{rattlesnake} in
#    my @f{/home/bob} buffer. I am on line 1, in Texinfo mode, and am at the
#    top of the buffer.
   Estoy visitando un fichero llamado @f{foo.texi}, en mi máquina
   @f{rattlesnake} en mi búfer @f{/home/bob}. Estoy en la línea 1, en
   modo Texinfo, y en la parte superior del búfer.

#    My @f{.emacs} file has a section that looks like this:
   Mi fichero @f{.emacs} tiene una sección que luce asi:

#    ..src > elisp
   ..src > elisp
#      ;; Set a Mode Line that tells me which machine, which directory,
#      ;; and which line I am on, plus the other customary information.
     ;; Configura una linea de modo que me dice en que máquina, directorio,
     ;; y línea estoy, ademas de la información habitual.
#      (setq-default mode-line-format
     (setq-default mode-line-format
#       (quote
      (quote
#        (#("-" 0 1
#           (help-echo
#            "mouse-1: select window, mouse-2: delete others ..."))
#         mode-line-mule-info
#         mode-line-modified
#         mode-line-frame-identification
       (#("-" 0 1
          (help-echo
           "mouse-1: seleccionar ventana\nmouse-2: eliminar otras ..."))
        mode-line-mule-info
        mode-line-modified
        mode-line-frame-identification
#         "    "
#         mode-line-buffer-identification
#         "    "
#         (:eval (substring
#                 (system-name) 0 (string-match "\\..+" (system-name))))
#         ":"
        "    "
        mode-line-buffer-identification
        "    "
        (:eval (substring
                (system-name) 0 (string-match "\\..+" (system-name))))
        ":"
#         default-directory
#         #(" " 0 1
#           (help-echo
#            "mouse-1: select window, mouse-2: delete others ..."))
#         (line-number-mode " Line %l ")
        default-directory
        #(" " 0 1
          (help-echo
           "mouse-1: seleccionar ventana\nmouse-2: eliminar otras ..."))
        (line-number-mode " Line %l ")
#         global-mode-string
#         #("   %[(" 0 6
#           (help-echo
#            "mouse-1: select window, mouse-2: delete others ..."))
#         (:eval (mode-line-mode-name))
        global-mode-string
        #("   %[(" 0 6
          (help-echo
           "mouse-1: seleccionar ventana\nmouse-2: eliminar otras ..."))
        (:eval (mode-line-mode-name))
#         mode-line-process
#         minor-mode-alist
#         #("%n" 0 2 (help-echo "mouse-2: widen" local-map (keymap ...)))
#         ")%] "
#         (-3 . "%P")
#         ;;   "-%-"
#         )))
        mode-line-process
        minor-mode-alist
        #("%n" 0 2 (help-echo "mouse-2: widen" local-map (keymap ...)))
        ")%] "
        (-3 . "%P")
        ;;   "-%-"
        )))
#    < src..
   < src..

#    Here, I redefine the default mode line. Most of the parts are from the
#    original; but I make a few changes. I set the @e{default} mode line
#    format so as to permit various modes, such as Info, to override it.
   Aquí, redefino la linea de modo por defecto. La mayoría de las partes son del
   original; pero hago algunos cambios. Estableci el formato de la linea de modo
   por @e{defecto} para permitir que varios modos, como Info, la sobreescriban.

#    Many elements in the list are self-explanatory: @c{mode-line-modified} is
#    a variable that tells whether the buffer has been modified, @c{mode-name}
#    tells the name of the mode, and so on. However, the format looks
#    complicated because of two features we have not discussed.
   Muchos elementos de la lista se explican por si mismos: @c{mode-line-modified}
   es una variable que indica si el búfer ha sido modificado, @c{mode-name}
   indica el nombre del modo, y así sucesivamente. Sin embargo, el formato
   parece complicado debido a dos caracteristicas que no hemos discutido.

#    The first string in the mode line is a dash or hyphen, @'c{-}. In the old
#    days, it would have been specified simply as @c{"-"}. But nowadays, Emacs
#    can add properties to a string, such as highlighting or, as in this case,
#    a help feature. If you place your mouse cursor over the hyphen, some help
#    information appears (By default, you must wait seven-tenths of a second
#    before the information appears. You can change that timing by changing
#    the value of @c{tooltip-delay}.)
   La primera cadena en la línea de modo es un guión, @'c(-). En los viejos tiempos,
   se habría especificado simplemente como @c("-"). Pero hoy en día, Emacs puede
   añadir propiedades a una cadena, como resaltado o, en este caso, una
   función de ayuda. Si colocas el cursor del ratón sobre el guión, aparece
   información de ayuda (de forma predeterminada, debe esperar siete décimas de
   segundo antes de que aparezca la información). Puedes cambiar esa
   temporización cambiando el valor de @c{tooltip-delay}.

#    The new string format has a special syntax:
   El nuevo formato de cadena tiene una sintaxis especial:

#    ..src > elisp
#      #("-" 0 1 (help-echo "mouse-1: select window, ..."))
#    < src..
   ..src > elisp
     #("-" 0 1 (help-echo "mouse-1: seleccionar ventana\n..."))
   < src..

#    The @c{#(} begins a list. The first element of the list is the string
#    itself, just one @'c{-}. The second and third elements specify the range
#    over which the fourth element applies. A range starts @e{after} a
#    character, so a zero means the range starts just before the first
#    character; a 1 means that the range ends just after the first character.
#    The third element is the property for the range. It consists of a
#    property list, a property name, in this case, @'c{help-echo}, followed by a
#    value, in this case, a string. The second, third, and fourth elements of
#    this new string format can be repeated.
   El @c{#(} inicia una lista. El primer elemento de la lista es la cadena en
   sí, solo un @'c{-}. El segundo y tercer elemento especifica el rango al que se
   aplica el cuarto elemento. Un rango empieza @e{después} de un carácter, por
   lo que un cero significa que el rango empieza justo después del primer caracter;
   un 1 significa que el rango termina justo después del primer caracter. El
   tercer elemento es la propiedad del rango. Consiste en una lista de
   propiedades, un nombre de propiedad, en este caso, @'c{help-echo}, seguido de
   un valor, en este caso, una cadena. El segundo, tercer y cuarto elemento de
   este nuevo formato de cadena se pueden repetir.

#    See Sections @l{elisp.html#Text Properties<>Text Properties}, and
#    @l{elisp.html#Mode Line Format<>Mode Line Format} in @e{The GNU Emacs Lisp
#    Reference Manual}, for more information.
   Para más información, consulta las Secciones @l{elisp.html#Text
   Properties<>Propiedades de Texto} y @l{elisp.html#Mode Line Format<>Formato
   de Linea de Modo} en @e{El Manual de Referencia de GNU Emacs Lisp}.

#    @c{mode-line-buffer-identification} displays the current buffer name. It
#    is a list beginning @c{(#("%12b" 0 4 …}. The @c{#(} begins the list.
   @c{mode-line-buffer-identification} muestra el nombre del buffer. Es una
   lista que inicia por @c{(#("%12b" 0 4 …}. El @c{#(} inicia la lista.

#    The @'c{"%12b"} displays the current buffer name, using the @c{buffer-name}
#    function with which we are familiar; the @'c(12) specifies the maximum number
#    of characters that will be displayed. When a name has fewer characters,
#    whitespace is added to fill out to this number.  (Buffer names can and
#    often should be longer than 12 characters; this length works well in a
#    typical 80 column wide window.)
   El @'c{"%12b"} muestra el nombre del actual búfer, usando la función
   @c{buffer-name} con la que estamos familiarizados; el @'c(12) especifica el
   número máximo de caracteres que serán mostrados. Cuando un nombre tiene
   pocos caracteres, el espacio en blanco se añade para rellenar este
   número. (Los nombres del búfer pueden y con frecuencia tendran mas de
   12 caracteres; esta longitud funciona bien en una típica ventana de 80
   columnas de ancho.)

#    @c{:eval} says to evaluate the following form and use the result as a
#    string to display. In this case, the expression displays the first
#    component of the full system name. The end of the first component is a
#    @'{.} (‘period’), so I use the @c{string-match} function to tell me the
#    length of the first component. The substring from the zeroth character to
#    that length is the name of the machine.
   @c{:eval} dice que hay que evaluar la siguiente forma y usar el resultado
   como una cadena para mostrar. En este caso, la expresión muestra el primer
   componente del nombre completo del sistema. El fin del primer componente es
   un @'{.}  (‘punto’), así que uso la función @c{string-match} para contar el
   tamaño del primer componente. La subcadena desde el caracter cero a este
   tamaño es el nombre de la máquina.

#    This is the expression:
   Esta es la expresión:

#    ..src > elisp
#      (:eval (substring
#              (system-name) 0 (string-match "\\..+" (system-name))))
#    < src..
   ..src > elisp
     (:eval (substring
             (system-name) 0 (string-match "\\..+" (system-name))))
   < src..

#    @'c{%[} and @'c{%]} cause a pair of square brackets to appear for each
#    recursive editing level.  @'c{%n} says ‘Narrow’ when narrowing is in
#    effect.  @'c{%P} tells you the percentage of the buffer that is above the
#    bottom of the window, or ‘Top’, ‘Bottom’, or ‘All’.  (A lower case @'c{p}
#    tell you the percentage above the @e{top} of the window.)  @'c{%-} inserts
#    enough dashes to fill out the line.
   @'c{%[} y @'c{%]} hacen que aparezca un par de corchetes por cada nivel de
   edición recursiva. @'c{%n} indica ‘Reducido’ cuando la reduccion esta en
   efecto. @'c{%P} indica el porcentaje del búfer que está por encima de la
   ventana, o ‘Top’, ‘Bottom’, o ‘All’. (Una @'c{p} minúscula indica el
   porcentaje por encima de la parte superior de la ventana.) @'c{%-} inserta
   suficientes guiones para rellenar la línea.

#    Remember, “You don't have to like Emacs to like it”––your own Emacs can
#    have different colors, different commands, and different keys than a
#    default Emacs.
   Recuerda, “No tiene que gustarte Emacs para que te guste”––Emacs puede tener
   diferentes colores, diferentes comandos y diferentes atajos que el Emacs por
   defecto.

#    On the other hand, if you want to bring up a plain ‘out of the box’ Emacs,
#    with no customization, type:
   Por otro lado, si quieres ‘sacar un Emacs de la caja’, sin
   personalización alguna, escribe:

#    ..src > sh
#      emacs -q
#    < src..
   ..src > sh
     emacs -q
   < src..

#    This will start an Emacs that does @e{not} load your @f{~/.emacs}
#    initialization file. A plain, default Emacs. Nothing more.
   Esto iniciara un Emacs que @e{no} cargue tu fichero de inicializacion
   @f{~/.emacs}. Un Emacs normal y corriente. Nada más.

# * Debugging
* Depurancion

#   GNU Emacs has two debuggers, @c{debug} and @c{edebug}. The first is built
#   into the internals of Emacs and is always with you; the second requires
#   that you instrument a function before you can use it.
  GNU Emacs tiene dos depuradores, @c{debug} y @c{edebug}. El primero esta
  incorporado nativamente dentro de Emacs y siempre está contigo; el segundo
  requiere que escribas una función antes de poder usarlo.

#   Both debuggers are described extensively in Section
#   @l{elisp.html#Debugging<>Debugging Lisp Programs} in @e{The GNU Emacs Lisp
#   Reference Manual}. In this chapter, I will walk through a short example of
#   each.
  Ambos depuradores se describen extensivamente en la Seccion
  @l{elisp.html#Debugging<>Depurando Programas Lisp} en @e{El Manual de
  Referencia de GNU Emacs Lisp}. En este capítulo, voy a explicar un breve ejemplo
  de cada uno de ellos.

# ** @c{debug}
** @c{debug}

#    Suppose you have written a function definition that is intended to return
#    the sum of the numbers 1 through a given number.  (This is the
#    @c{triangle} function discussed earlier. See Section @l{#Example with
#    Decrementing Counter}, for a discussion.)
   Supón que has escrito una definición de función que pretende devolver la suma
   de los números números desde 1 a un número dado. (Esta es la función
   @c{triangulo} discutida anteriormente. Para mas información, consulta la
   Seccion @l{#Ejemplo con contador decreciente}.)

#    However, your function definition has a bug. You have mistyped @c{1=} for
#    @c{1-}. Here is the broken definition:
   Sin embargo, tu definición de función tiene un error. Has escrito
   @c{1=} en lugar de @c{1-}. Aquí está la definición rota:

#    ..src > elisp
#      (defun triangle-bugged (number)
#        "Return sum of numbers 1 through NUMBER inclusive."
#        (let ((total 0))
#          (while (> number 0)
#            (setq total (+ total number))
#            (setq number (1= number)))      ; Error here.
#          total))
#    < src..
   ..src > elisp
     (defun triangulo-defectuoso (numero)
       "Devuelve la suma de números desde el 1 hasta e incluyendo a NUMERO."
       (let ((total 0))
         (while (> numero 0)
           (setq total (+ total numero))
           (setq numero (1= numero)))     ; Error aquí.
         total))
   < src..

#    If you are reading this in Info, you can evaluate this definition in the
#    normal fashion. You will see @c{triangle-bugged} appear in the echo area.
   Si estas leyendo esto en Emacs, puedes evaluar la definición de la manera
   habitual. Veras aparecer @c{triangulo-defectuoso} en el área de eco.

#    Now evaluate the @c{triangle-bugged} function with an argument of 4:
   Ahora evalúa la función @c{triangulo-defectuoso} con un argumento de 4:

#    ..src > elisp
#      (triangle-bugged 4)
#    < src..
   ..src > elisp
     (triangulo-defectuoso 4)
   < src..

#    In a recent GNU Emacs, you will create and enter a @f{*Backtrace*} buffer
#    that says:
   En un GNU Emacs reciente, se creará e ingresaras a un búfer
   @f{*Backtrace*} que dice:

#  ..example >
#    ---------- Buffer: *Backtrace* ----------
#    Debugger entered--Lisp error: (void-function 1=)
#      (1= number)
#      (setq number (1= number))
#      (while (> number 0) (setq total (+ total number))
#            (setq number (1= number)))
#      (let ((total 0)) (while (> number 0) (setq total ...)
#        (setq number ...)) total)
#      triangle-bugged(4)
#      eval((triangle-bugged 4))
#      eval-last-sexp-1(nil)
#      eval-last-sexp(nil)
#      call-interactively(eval-last-sexp)
#    ---------- Buffer: *Backtrace* ----------
#  < example..
   ..example >
     ---------- Buffer: *Backtrace* ----------
     Debugger entered--Lisp error: (void-function 1=)
       (1= numero)
       (setq numero (1= numero))
       (while (> numero 0)
          (setq total (+ total numero))
          (setq numero (1= numero)))
       (let ((total 0))
          (while (> numero 0)
            (setq total (+ total numero))
            (setq numero (1= numero)))
         total)
       triangulo-defectuoso(4)
       eval((triangulo-defectuoso 4) nil)
       elisp--eval-last-sexp(nil)
       eval-last-sexp(nil)
       call-interactively(eval-last-sexp)
     ---------- Buffer: *Backtrace* ----------
   < example..

#    (I have reformatted this example slightly; the debugger does not fold long
#    lines. As usual, you can quit the debugger by typing @k{q} in the
#    @f{*Backtrace*} buffer.)
   (He reformateado ligeramente este ejemplo; el depurador no corta las lineas
   largas. Como de costumbre, se puede salir del depurador escribiendo @k{q} en el
   buffer @f{*Backtrace*}.)

#    In practice, for a bug as simple as this, the ‘Lisp error’ line will tell
#    you what you need to know to correct the definition. The function @c{1=}
#    is ‘void’.
   En la práctica, para un error tan simple como este, la línea de ‘error
   Lisp’ dira lo que se necesita saber para corregir la definición. La
   función @c{1=} está ‘vacía’.

#    However, suppose you are not quite certain what is going on?  You can read
#    the complete backtrace.
   Sin embargo, suponiendo que no estas seguro de lo que está pasando, puedes
   leer el registro completo.

#    In this case, you need to run a recent GNU Emacs, which automatically
#    starts the debugger that puts you in the @f{*Backtrace*} buffer; or else,
#    you need to start the debugger manually as described below.
   En este caso, necesitas ejecutar una versión reciente de GNU Emacs, que
   inicie automáticamente el depurador que te coloca en el búfer
   @f{*Backtrace*}; o bien, necesitas iniciar manualmente el depurador como
   se describe a continuacion.

#    Read the @f{*Backtrace*} buffer from the bottom up; it tells you what
#    Emacs did that led to the error. Emacs made an interactive call to
#    @k{C-x C-e} @%c(eval-last-sexp), which led to the evaluation of the
#    @c{triangle-bugged} expression. Each line above tells you what the Lisp
#    interpreter evaluated next.
   Lee el búfer @f{*Backtrace*} de abajo hacia arriba; emacs te informa la causa
   que provoco el error. Emacs hizo una llamada interactiva a @k{C-x C-e}
   @%c(eval-last-sexp), que produjo la evaluación de la expresión
   @c{triangulo-defectuoso}. Cada línea anterior cuenta lo que el intérprete
   Lisp evaluó a continuacion.

#    The third line from the top of the buffer is
   La tercera línea iniciando en la parte superior del búfer es

#    ..src > elisp
#      (setq number (1= number))
#    < src..
   ..src > elisp
     (setq number (1= number))
   < src..

#    Emacs tried to evaluate this expression; in order to do so, it tried to
#    evaluate the inner expression shown on the second line from the top:
   Emacs intentó evaluar esta expresión; para ello, intentó evaluar
   la expresión interna mostrada en la segunda línea desde arriba:

#    ..src > elisp
#      (1= number)
#    < src..
   ..src > elisp
     (1= number)
   < src..

#    This is where the error occurred; as the top line says:
   Aquí es donde ocurrio el error; como dice en la línea superior:

#    ..example >
#      Debugger entered--Lisp error: (void-function 1=)
#    < example..
   ..example >
     Debugger entered--Lisp error: (void-function 1=)
   < example..

#    You can correct the mistake, re-evaluate the function definition, and then
#    run your test again.
   Puedes corregir el error, reevalúar la definición de función, y a continuacion
   ejecutar de nuevo la prueba.

# ** @c{debug-on-entry}
** @c{debug-on-entry}

#    A recent GNU Emacs starts the debugger automatically when your function
#    has an error.
   Un GNU Emacs actual inicia el depurador automáticamente cuando la función
   tiene un error.

#    Incidentally, you can start the debugger manually for all versions of
#    Emacs; the advantage is that the debugger runs even if you do not have a
#    bug in your code. Sometimes your code will be free of bugs!
   Por cierto, se puede iniciar el depurador manualmente para todas las
   versiones de Emacs; la ventaja es que el depurador se ejecuta incluso si
   no hay ningun error en el código. Algunas veces, ¡tu código estará libre
   de errores!

#    You can enter the debugger when you call the function by calling
#    @c{debug-on-entry}.
   Puedes entrar en el depurador llamando a la función @c{debug-on-entry}.

#    Type:
   Presiona:

#    ..example >
#      M-x debug-on-entry RET triangle-bugged RET
#    < example..
   ..example >
     M-x debug-on-entry RET triangulo-defectuoso RET
   < example..

#    Now, evaluate the following:
   Ahora, evalúa lo siguiente:

#    ..src > elisp
#      (triangle-bugged 5)
#    < src..
   ..src > elisp
     (triangulo-defectuoso 5)
   < src..

#    All versions of Emacs will create a @f{*Backtrace*} buffer and tell you
#    that it is beginning to evaluate the @c{triangle-bugged} function:
   Todas las versiones de Emacs crearán un búfer @f{*Backtrace*} e informaran
   que estas iniciando la evaluacion de la función @c{triangulo-defectuoso}:

#   ..example >
#     ---------- Buffer: *Backtrace* ----------
#     Debugger entered--entering a function:
#     * triangle-bugged(5)
#       eval((triangle-bugged 5))
#       eval-last-sexp-1(nil)
#       eval-last-sexp(nil)
#       call-interactively(eval-last-sexp)
#     ---------- Buffer: *Backtrace* ----------
#   < example..
   ..example >
     ---------- Buffer: *Backtrace* ----------
     Debugger entered--entering a function:
     * triangulo-defectuoso(5)
       eval((triangulo-defectuoso 5))
       eval-last-sexp-1(nil)
       eval-last-sexp(nil)
       call-interactively(eval-last-sexp)
     ---------- Buffer: *Backtrace* ----------
   < example..

#    In the @f{*Backtrace*} buffer, type @k{d}. Emacs will evaluate the first
#    expression in @c{triangle-bugged}; the buffer will look like this:
   Ya en el búfer @f{*Backtrace*}, pulsa @k{d}. Emacs evaluará la primer
   expresión en @c{triangulo-defectuoso}; el búfer tendra este aspecto:

#   ..example >
#     ---------- Buffer: *Backtrace* ----------
#     Debugger entered--beginning evaluation of function call form:
#     * (let ((total 0)) (while (> number 0) (setq total ...)
#             (setq number ...)) total)
#     * triangle-bugged(5)
#       eval((triangle-bugged 5))
#       eval-last-sexp-1(nil)
#       eval-last-sexp(nil)
#       call-interactively(eval-last-sexp)
#     ---------- Buffer: *Backtrace* ----------
#   < example..
   ..example >
     ---------- Buffer: *Backtrace* ----------
     Debugger entered--beginning evaluation of function call form:
     * (let ((total 0)) (while (> numero 0) (setq total ...)
             (setq numero ...)) total)
     * triangulo-defectuoso(5)
       eval((triangulo-defectuoso 5))
       eval-last-sexp-1(nil)
       eval-last-sexp(nil)
       call-interactively(eval-last-sexp)
     ---------- Buffer: *Backtrace* ----------
   < example..

#    Now, type @k{d} again, eight times, slowly. Each time you type @k{d},
#    Emacs will evaluate another expression in the function definition.
   Ahora, presiona @k{d} de nuevo, ocho veces, lentamente. Cada vez que
   presionas @k{d} Emacs evaluará otra expresión en la definición de función.

#    Eventually, the buffer will look like this:
   Eventualmente, el búfer se vera asi:

#   ..example >
#     ---------- Buffer: *Backtrace* ----------
#     Debugger entered--beginning evaluation of function call form:
#     * (setq number (1= number))
#     * (while (> number 0) (setq total (+ total number))
#             (setq number (1= number)))
#     * (let ((total 0)) (while (> number 0) (setq total ...)
#             (setq number ...)) total)
#     * triangle-bugged(5)
#       eval((triangle-bugged 5))
#       eval-last-sexp-1(nil)
#       eval-last-sexp(nil)
#       call-interactively(eval-last-sexp)
#     ---------- Buffer: *Backtrace* ----------
#   < example..
   ..example >
     ---------- Buffer: *Backtrace* ----------
     Debugger entered--beginning evaluation of function call form:
     * (setq numero (1= numero))
     * (while (> numero 0) (setq total (+ total numero))
             (setq numero (1= numero)))
     * (let ((total 0)) (while (> numero 0) (setq total ...)
             (setq numero ...)) total)
     * triangulo-defectuoso(5)
       eval((triangulo-defectuoso 5))
       eval-last-sexp-1(nil)
       eval-last-sexp(nil)
       call-interactively(eval-last-sexp)
     ---------- Buffer: *Backtrace* ----------
   < example..

#    Finally, after you type @k{d} two more times, Emacs will reach the error,
#    and the top two lines of the @f{*Backtrace*} buffer will look like this:
   Finalmente, después de escribir @k{d} dos veces más, Emacs llegara al error
   y las dos líneas superiores del buffer @f{*Backtrace*} se veran así:

#   ..example >
#     ---------- Buffer: *Backtrace* ----------
#     Debugger entered--Lisp error: (void-function 1=)
#     * (1= number)
#     …
#     ---------- Buffer: *Backtrace* ----------
#   < example..
   ..example >
     ---------- Buffer: *Backtrace* ----------
     Debugger entered--Lisp error: (void-function 1=)
     * (1= numero)
     …
     ---------- Buffer: *Backtrace* ----------
   < example..

#    By typing @k{d}, you were able to step through the function.
   Presionando @k{d}, fuiste capaz de pasear a través de la función.

#    You can quit a @f{*Backtrace*} buffer by typing @k{q} in it; this quits
#    the trace, but does not cancel @c{debug-on-entry}.
   Se puede salir de un buffer @f{*Backtrace*} pulsando @k{q}; esto cierra
   el registro, pero no cancela @c{debug-on-entry}.

#    To cancel the effect of @c{debug-on-entry}, call @c{cancel-debug-on-entry}
#    and the name of the function, like this:
   Para cancelar el efecto de @c{debug-on-entry}, llama a
   @c{cancel-debug-on-entry} y el nombre de la función, asi:

#    ..example >
#      M-x cancel-debug-on-entry RET triangle-bugged RET
#    < example..
   ..example >
     M-x cancel-debug-on-entry RET triangulo-defectuoso RET
   < example..

#    (If you are reading this in Info, cancel @c{debug-on-entry} now.)
   (Si está leyendo esto en Emacs, cancela @c{debug-on-entry} ahora.)

# ** @c{debug-on-quit} and @c{(debug)}
** @c{debug-on-quit} y @c{(debug)}

#    In addition to setting @c{debug-on-error} or calling @c{debug-on-entry},
#    there are two other ways to start @c{debug}.
   Ademas de configurar @c{debug-on-error} o llamar a @c{debug-on-entry}, hay
   otras dos maneras de iniciar @c{debug}.

#    You can start @c{debug} whenever you type @k{C-g} @%c(keyboard-quit) by
#    setting the variable @c{debug-on-quit} to @c{t}. This is useful for
#    debugging infinite loops.
   Puedes iniciar @c{debug} cada vez que presiones @k{C-g} @%c(keyboard-quit)
   configurando la variable @c{debug-on-quit} en @c{t}. Esto es útil para
   depurar bucles infinitos.

#    Or, you can insert a line that says @c{(debug)} into your code where you
#    want the debugger to start, like this:
   O bien, puedes insertar un línea que diga @c{(debug)} dentro de tu código
   donde quieras que inicie el depurador, así:

#    ..src > elisp
#      (defun triangle-bugged (number)
#        "Return sum of numbers 1 through NUMBER inclusive."
#        (let ((total 0))
#          (while (> number 0)
#            (setq total (+ total number))
#            (debug)                         ; Start debugger.
#            (setq number (1= number)))      ; Error here.
#          total))
#    < src..
   ..src > elisp
     (defun triangulo-defectuoso (numero)
       "Devuelve la suma de números desde el 1 hasta e incluyendo a NUMERO."
       (let ((total 0))
         (while (> numero 0)
           (setq total (+ total numero))
           (debug)                         ; Empieza el depurador.
           (setq number (1= number)))      ; Error aquí.
         total))
   < src..

#    The @c{debug} function is described in detail in Section
#    @l{elisp.html#Debugger<>The Lisp Debugger} in @e{The GNU Emacs Lisp
#    Reference Manual}.
   La función @c{debug} se describe en detalle en @l{elisp.html#Debugger<>El
   Depurador Lisp} en @e{El Manual de Referencia GNU Emacs Lisp}.

# ** The @c{edebug} Source Level Debugger
** El depurador de nivel de fuente @c{edebug}

#    Edebug is a source level debugger. Edebug normally displays the source of
#    the code you are debugging, with an arrow at the left that shows which
#    line you are currently executing.
   Edebug es un depurador a nivel de fuente. Edebug normalmente muestra
   el codigo fuente que estás depurando, con una flecha a la
   izquierda que muestra que línea se está ejecutando actualmente.

#    You can walk through the execution of a function, line by line, or run
#    quickly until reaching a @:{breakpoint} where execution stops.
   Es posible desplazarse a través de la ejecución de una función, línea a línea, o
   ejecutarla rápidamente hasta alcanzar un @:{punto de ruptura} donde la
   ejecución se detenga.

#    Edebug is described in Section @l{elisp.html#Edebug<>Edebug} in @e{The GNU
#    Emacs Lisp Reference Manual}.
   Edebug se describe en la Seccion @l{elisp.html#Edebug<>Edebug} en @e{El
   Manual de Referencia de GNU Emacs Lisp}.

#    Here is a bugged function definition for @c{triangle-recursively}. See
#    Section @l{#Recursion in place of a counter}, for a review of it.
   Aquí hay una función con errores de @c{triangulo-recursivo}. Consulta la
   Sección @l{#Recursión en lugar de un contador}, para una revisión de la misma.

#    ..src > elisp
#      (defun triangle-recursively-bugged (number)
#        "Return sum of numbers 1 through NUMBER inclusive.
#      Uses recursion."
#        (if (= number 1)
#            1
#          (+ number
#             (triangle-recursively-bugged
#              (1= number)))))               ; Error here.
#    < src..
   ..src > elisp
     (defun triangulo-recursivo-defectuoso (numero)
       "Devuelve la suma de números desde el 1 hasta e incluyendo a NUMERO.
     Usa recursion."
       (if (= numero 1)
           1
         (+ numero
            (triangulo-recursivo-defectuoso
             (1= numero)))))                 ; Error aquí.
   < src..

#    Normally, you would install this definition by positioning your cursor
#    after the function's closing parenthesis and typing @k{C-x C-e}
#    @%c(eval-last-sexp) or else by positioning your cursor within the
#    definition and typing @k{C-M-x} @%c(eval-defun).  (By default, the
#    @c{eval-defun} command works only in Emacs Lisp mode or in Lisp
#    Interaction mode.)
   Normalmente, se instalaría esta definición colocando el cursor después
   del parentesis que cierra la funcion y presionando @k{C-x C-e}
   @%c(eval-last-sexp) o bien colocando el cursor dentro de la definición y
   escribiendo @k{C-M-x} @%c(eval-defun). (Por defecto, el comando
   @c{eval-defun} solo funciona en modo Emacs Lisp o en el modo
   interactivo de Lisp.)

#    However, to prepare this function definition for Edebug, you must first
#    @:{instrument} the code using a different command. You can do this by
#    positioning your cursor within or just after the definition and typing
   Sin embargo, para preparar esta definición de función para Edebug, se debe
   primero @:{instrumentar} el código usando un comando diferente. Se puede
   hacer esto colocando el cursor dentro o justo después de la definición y
   escribir

#    ..example >
#      M-x edebug-defun RET
#    < example..
   ..example >
     M-x edebug-defun RET
   < example..

#    This will cause Emacs to load Edebug automatically if it is not already
#    loaded, and properly instrument the function.
   Esto hará que Emacs cargue Edebug automáticamente si aun no está
   cargado, y que intrumente correctamente la función.

#    After instrumenting the function, place your cursor after the following
#    expression and type @k{C-x C-e} @%c(eval-last-sexp):
   Después de instrumentar la función, coloca el cursor después de la siguiente
   expresión y escribe @k{C-x C-e} @%c(eval-last-sexp):

#    ..src > elisp
#      (triangle-recursively-bugged 3)
#    < src..
   ..src > elisp
     (triangulo-recursivo-defectuoso 3)
   < src..

#    You will be jumped back to the source for @c{triangle-recursively-bugged}
#    and the cursor positioned at the beginning of the @c{if} line of the
#    function. Also, you will see an arrowhead at the left hand side of that
#    line. The arrowhead marks the line where the function is executing.  (In
#    the following examples, we show the arrowhead with @'{=>}; in a windowing
#    system, you may see the arrowhead as a solid triangle @%'(▸) in the window
#    ‘fringe’.)
   Saltaras de nuevo al codigo fuente de @c{triangulo-recursivo-defectuoso} y
   el cursor estara al principio de la linea @c{if} de la
   función. Ademas, verás la punta de una flecha a la izquierda de esa
   línea donde se está ejecutando la función. (En los siguientes ejemplos, se
   muestra la flecha con @'{=>}; en un sistema de ventanas, se puede ver la
   flecha como un triángulo sólido @%'(▸) en el @'(borde) de la ventana.)

#    ..example >
#      =>★(if (= number 1)
#    < example..
   ..example >
     =>★(if (= numero 1)
   < example..

#    In the example, the location of point is displayed with a star, @'{★}.
   En el ejemplo, la posición del punto se muestra con una estrella, @'{★}.

#    If you now press @k{SPC}, point will move to the next expression to be
#    executed; the line will look like this:
   Si ahora presionas @k{SPC}, el punto se moverá a la siguiente expresión
   a ser ejecutada; la línea se vera asi:

#    ..example >
#      =>(if ★(= number 1)
#    < example..
   ..example >
     =>(if ★(= numero 1)
   < example..

#    As you continue to press @k{SPC}, point will move from expression to
#    expression. At the same time, whenever an expression returns a value,
#    that value will be displayed in the echo area. For example, after you
#    move point past @c{number}, you will see the following:
   Al continuar presionando @k{SPC}, el punto se moverá de una
   expresión a otra. Al mismo tiempo, siempre que una expresión
   devuelva un valor, este valor se mostrara en el área de eco. Por ejemplo,
   después de mover el punto pasado @c{numero}, se verá lo siguiente:

#    ..example >
#      Result: 3 (#o3, #x3, ?\C-c)
#    < example..
   ..example >
     Result: 3 (#o3, #x3, ?\C-c)
   < example..

#    This means the value of @c{number} is 3, which is octal three, hexadecimal
#    three, and @A{ASCII} ‘control-c’ (the third letter of the alphabet, in
#    case you need to know this information).
   Esto significa que el valor de @c{numero} es 3, que es tres en octal, tres
   en hexadecimal, y ‘control-c’ en @A{ASCII} (la tercer letra del alfabeto, en
   caso de que se necesite conocer esta información).

#    You can continue moving through the code until you reach the line with the
#    error. Before evaluation, that line looks like this:
   Puedes continuar moviéndote a través del código hasta que llegues a la
   línea con el error. Antes de la evaluación, esta línea se ve asi:

#    ..example >
#      =>        ★(1= number)))))               ; Error here.
#    < example..
   ..example >
     =>        ★(1= numero)))))               ; Error aquí.
   < example..

#    When you press @k{SPC} once again, you will produce an error message that
#    says:
   Cuando presiones @k{SPC} de nuevo, aparecera un mensaje de error que dice:

#    ..example >
#      Symbol's function definition is void: 1=
#    < example..
   ..example >
     Symbol's function definition is void: 1=
   < example..

#    This is the bug.
   Este es el error.

#    Press @k{q} to quit Edebug.
   Presiona @k{q} para salir de Edebug.

#    To remove instrumentation from a function definition, simply re-evaluate
#    it with a command that does not instrument it. For example, you could
#    place your cursor after the definition's closing parenthesis and type
#    @k{C-x C-e}.
   Para eliminar la instrumentación de una definición de función,
   simplemente se reevalúa con un comando que no la instrumente. Por ejemplo,
   se podría colocar el cursor después del parentesis que cierra la definición
   y presionar @k{C-x C-e}.

#    Edebug does a great deal more than walk with you through a function. You
#    can set it so it races through on its own, stopping only at an error or at
#    specified stopping points; you can cause it to display the changing values
#    of various expressions; you can find out how many times a function is
#    called, and more.
   Edebug hace mucho mas que caminar atravez de una función. Se puede configurar
   para que corra por si solo, deteniendose solo en un error o en puntos
   específicos, se puede hacer que muestre los valores cambiantes de varias
   expresiones; encontrar cuantas veces se llama a una función, y mucho más.

#    Edebug is described in Section @l{elisp.html#Edebug<>Edebug} in @e{The GNU
#    Emacs Lisp Reference Manual}.
   Edebug se describe en @l{elisp.html#Edebug<>Edebug} en @e{El Manual de
   Referencia de GNU Emacs Lisp}.

# ** Debugging Exercises
** Ejercicios de depuración

#    - Install the @c{count-words-example} function and then cause it to enter the
#      built-in debugger when you call it. Run the command on a region
#      containing two words. You will need to press @k{d} a remarkable number
#      of times. On your system, is a ‘hook’ called after the command
#      finishes?  (For information on hooks, see Section @l{elisp.html#Command
#      Overview<>Command Loop Overview} in @e{The GNU Emacs Lisp Reference
#      Manual}.)
   - Instala la función @c{count-words-example} y luego haz que entre en el
     depurador cuando se llame. Ejecuta el comando en una región que contenga
     dos palabras. Tendras que presionar @k{d} un número considerable de
     veces. En tu sistema, ¿se llama a un ‘hook’ cuando termina el comando?. (Para
     mas información sobre los hooks, consulta la Seccion @l{elisp.html#Command
     Overview<>Command Overview} en @e{El Manual de Referencia de GNU Emacs Lisp}.)

#    - Copy @c{count-words-example} into the @f{*scratch*} buffer, instrument the
#      function for Edebug, and walk through its execution. The function does
#      not need to have a bug, although you can introduce one if you wish. If
#      the function lacks a bug, the walk-through completes without problems.
   - Copia @c{count-words-example} dentro del búfer @f{*scratch*}, instrumenta
     la función para Edebug, y navega a través de su ejecución. La función
     no necesita tener un error, aunque se puede introducir uno si se
     desea. Si la función carece de errores, el recorrido se completa sin
     problemas.

#    - While running Edebug, type @k{?} to see a list of all the Edebug
#      commands.  (The @c{global-edebug-prefix} is usually @k{C-x X}, i.e.,
#      @k{@k{CTRL}-x} followed by an upper case @k{X}; use this prefix for
#      commands made outside of the Edebug debugging buffer.)
   - Mientras se ejecuta Edebug, presiona @k{?} para ver una lista de todos
     los comandos Edebug. (El @c{global-edebug-prefix} normalmente es @k{C-x
     X}, es decir: @k{CTRL-x} seguido por una tecla mayúscula @k{X}; utuliza
     este prefijo para realizar comandos fuera del búfer de depuración
     Edebug.)

#    - In the Edebug debugging buffer, use the @k{p} @%c(edebug-bounce-point)
#      command to see where in the region the @c{count-words-example} is working.
   - En el búfer de depuración Edebug, usa el comando @k{p}
     @%c(edebug-bounce-point) para ver en que parte de la region esta trabajando
     @c{count-words-example}.

#    - Move point to some spot further down the function and then type the
#      @k{h} @%c(edebug-goto-here) command to jump to that location.
   - Mueve el punto a algún sitio mas abajo en la función y luego utiliza el
     comando @k{h} @%c(edebug-goto-here) para saltar a esa localización.

#    - Use the @k{t} @%c(edebug-trace-mode) command to cause Edebug to walk
#      through the function on its own; use an upper case @k{T} for
#      @c{edebug-Trace-fast-mode}.
   - Usa el comando @k{t} @%c(edebug-trace-mode) para hacer que Edebug
     recorra la funcion por si mismo; usa una @k{T} mayúscula para
     @c{edebug-Trace-fast-mode}.

#    - Set a breakpoint, then run Edebug in Trace mode until it reaches the
#      stopping point.
   - Asigna un punto de ruptura, luego ejecuta Edebug en modo Trace hasta
     que alcance el punto de parada.

# * Conclusion
* Conclusión

#   We have now reached the end of this Introduction. You have now learned
#   enough about programming in Emacs Lisp to set values, to write simple
#   @f{.emacs} files for yourself and your friends, and write simple
#   customizations and extensions to Emacs.
  Hemos llegado al fin de esta Introducción. Has aprendido lo suficiente sobre
  programación en Emacs Lisp para establecer valores, escribir ficheros
  @f{.emacs} para tí y tus amigos, y escribir personalizaciones y
  extensiones simples para Emacs.

#   This is a place to stop. Or, if you wish, you can now go onward, and teach
#   yourself.
  Este es un lugar para parar. O, si lo deseas, seguir adelante, y
  aprender por ti mismo.

#   You have learned some of the basic nuts and bolts of programming. But only
#   some. There are a great many more brackets and hinges that are easy to use
#   that we have not touched.
  Se han aprendido algunos de los aspectos basicos de la programación. Pero solo
  algunos. Todavía hay muchos conceptos que son fáciles de usar y que no hemos
  tocado.

#   A path you can follow right now lies among the sources to GNU Emacs and in
#   @e{The GNU Emacs Lisp Reference Manual}.
  Otra ruta a seguir ahora mismo se encuentra entre el codigo fuente de Emacs y
  en @e{El Manual de Referencia de GNU Emacs}.

#   The Emacs Lisp sources are an adventure. When you read the sources and
#   come across a function or expression that is unfamiliar, you need to figure
#   out or find out what it does.
  El codigo de Emacs Lisp es una aventura. Cuando lo lees y te encuentras con una
  función o expresión que no es familiar, necesitas imaginar o averiguar lo
  qué hace.

#   Go to the Reference Manual. It is a thorough, complete, and fairly
#   easy-to-read description of Emacs Lisp. It is written not only for
#   experts, but for people who know what you know.  (The @q{Reference Manual}
#   comes with the standard GNU Emacs distribution. Like this introduction, it
#   comes as a Texinfo source file, so you can read it on-line and as a
#   typeset, printed book.)
  Consulta el Manual de Referencia. Es una descripcion completa y bastante fácil
  de leer de Emacs Lisp. Está escrito no solo para expertos, sino tambien para
  personas que saben lo que tu sabes. (El @e{Manual de Referencia} viene con la
  distribución de GNU Emacs. Al igual que esta introducción, viene como un
  fichero fuente de Texinfo, para que puedas leerlo en linea y como una
  composicion tipografica, o como un libro impreso.)

#   Go to the other on-line help that is part of GNU Emacs: the on-line
#   documentation for all functions and variables, and @c{find-tag}, the
#   program that takes you to sources.
  Puedes acudir a la ayuda en linea que es parte de GNU Emacs: la documentación
  en linea para todas las funciones y variables, y @c{find-tag}, el programa que
  te lleva al codigo fuente.

#   Here is an example of how I explore the sources. Because of its name,
#   @f{simple.el} is the file I looked at first, a long time ago. As it
#   happens some of the functions in @f{simple.el} are complicated, or at least
#   look complicated at first sight. The @c{open-line} function, for example,
#   looks complicated.
  He aquí un ejemplo de cómo exploro las fuentes. Por su nombre, @f{simple.el}
  es el fichero que mire primero, hace mucho tiempo. Ocurre que algunas de las
  funciones en @f{simple.el} son complicadas, o al menos parecen complicadas a
  primera vista. La función @c{open-line}, por ejemplo, parece complicada.

#   You may want to walk through this function slowly, as we did with the
#   @c{forward-sentence} function.  (See Section @l{#The @c{forward-sentence} Function}.)  Or
#   you may want to skip that function and look at another, such as
#   @c{split-line}. You don't need to read all the functions. According to
#   @c{count-words-in-defun}, the @c{split-line} function contains 102 words
#   and symbols.
  Es posible que desees explorar esta función lentamente, como
  hicimos con la función @c{forward-sentence}. (Consulta la Seccion @l{#La función
  @c{forward-sentence}}.) O tal vez quieras saltarte esta función y mirar
  otra, como @c{split-line}. No es necesario leer todas las funciones. Segun
  @c{contar-palabras-en-definicion}, la función @c{split-line} contiene 102
  palabras y símbolos.

#   Even though it is short, @c{split-line} contains expressions we have not
#   studied: @c{skip-chars-forward}, @c{indent-to}, @c{current-column} and
#   @c{insert-and-inherit}.
  Aunque es pequeña, @c{split-line} contiene expresiones que no hemos
  estudiado: @c{skip-chars-forward}, @c{indent-to}, @c{current-column} e
  @c{insert-and-inherit}.

#   Consider the @c{skip-chars-forward} function.  (It is part of the function
#   definition for @c{back-to-indentation}, which is shown in Section
#   @l{#Review: How To Write Function Definitions<>Review}.)
  Considera la función @c{skip-chars-forward}. (Forma parte de la definición de
  función para @c{back-to-indentation}, que se muestra en la Seccion de
  @l(#Repaso: Cómo escribir definiciones de funcion<>Repaso).)

#   In GNU Emacs, you can find out more about @c{skip-chars-forward} by typing
#   @k{C-h f} @%c(describe-function) and the name of the function. This gives
#   you the function documentation.
  En GNU Emacs, puedes encontrar más informacion acerca de @c{skip-chars-forward}
  presionando @k{C-h f} @%c(describe-function) y el nombre de la función. Esto
  te proporciana la documentación de la función.

#   You may be able to guess what is done by a well named function such as
#   @c{indent-to}; or you can look it up, too. Incidentally, the
#   @c{describe-function} function itself is in @f{help.el}; it is one of those
#   long, but decipherable functions. You can look up @c{describe-function}
#   using the @k{C-h f} command!
  Puedes ser capaz de adivinar lo que hace una función con un buen nombre como
  @c{indent-to}; o en su defecto puedes buscar su descripcion. Por cierto, la
  función @c{describe-function} en sí misma está en @f{help.el}; es una de esas
  funciones largas, pero descifrables. ¡Puedes buscar @c{describe-function}
  usando el comando @k{C-h f}!

#   In this instance, since the code is Lisp, the @f{*Help*} buffer contains
#   the name of the library containing the function's source. You can put
#   point over the name of the library and press the RET key, which in this
#   situation is bound to @c{help-follow}, and be taken directly to the source,
#   in the same way as @k{M-.} @%c(find-tag).
  En este caso, dado que el código es Lisp, el búfer @f{*Help*} contiene
  el nombre de la librería que contiene el origen de la función. Puedes
  colocar el punto sobre el nombre de la librería y pulsar la tecla RET,
  que en está situación está asociada a @c{help-follow}, y ser llevado
  directamente al codigo fuente, de la misma manera que con @k{M-.} @%c(find-tag).

#   The definition for @c{describe-function} illustrates how to customize the
#   @c{interactive} expression without using the standard character codes; and
#   it shows how to create a temporary buffer.
  La definición para @c{describe-function} ilustra como personalizar las
  expresiones @c{interactive} sin usar los códigos de caracter estándar y
  muestra como crear un búfer temporal.

#   (The @c{indent-to} function is written in C rather than Emacs Lisp; it is a
#   ‘built-in’ function.  @c{help-follow} takes you to its source as does
#   @c{find-tag}, when properly set up.)
  (La función @c{indent-to} esta escrita en C en lugar de Emacs Lisp; es una
  función ‘nativa’. Cuando se configura correctamente, @c{help-follow} te lleva
  a su fuente al igual que @c{find-tag}.)

#   You can look at a function's source using @c{find-tag}, which is bound to
#   @k{M-.}  Finally, you can find out what the Reference Manual has to say by
#   visiting the manual in Info, and typing @k{i} @%c(Info-index) and the name
#   of the function, or by looking up the function in the index to a printed
#   copy of the manual.
  Puedes mirar la fuente de una función usando @c{find-tag}, que está
  vinculada a @k{M-.}. Finalmente, puedes encontrar lo que el Manual de
  Referencia tiene que decir visitando el manual en Info, e ingresando
  @k{i} @%c(Info-index) y el nombre de la función, o buscando la función en el
  índice de una copia impresa del manual.

#   Similarly, you can find out what is meant by @c{insert-and-inherit}.
  Del mismo modo, puedes encontrar que significa mediante @c{insert-and-inherit}.

#   Other interesting source files include @f{paragraphs.el}, @f{loaddefs.el},
#   and @f{loadup.el}. The @f{paragraphs.el} file includes short, easily
#   understood functions as well as longer ones. The @f{loaddefs.el} file
#   contains the many standard autoloads and many keymaps. I have never looked
#   at it all; only at parts.  @f{loadup.el} is the file that loads the
#   standard parts of Emacs; it tells you a great deal about how Emacs is
#   built.  (See Section @l{elisp.html#Building Emacs<>Building Emacs} in
#   @e{The GNU Emacs Lisp Reference Manual}, for more about building.)
  Otros ficheros fuente interesantes son @f{paragraphs.el}, @f{loaddefs.el} y
  @f{loadup.el}. El fichero @f{paragraphs.el} incluye funciones cortas y faciles
  de entender, asi como funciones mas extensas. El fichero @f{loaddefs.el}
  contiene muchos autoloads estándar y muchos mapas de teclado. Nunca he visto
  todo; solo algunas partes. @f{loadup.el} es el fichero que carga las partes
  estándar de Emacs; te dice mucho sobre como se construye Emacs. (Para mas
  informacion, consulta la Seccion @l{elisp.html#Building Emacs<>Construyendo
  Emacs} en @e{El Manual de Referencia de GNU Emacs Lisp}.)

#   As I said, you have learned some nuts and bolts; however, and very
#   importantly, we have hardly touched major aspects of programming; I have
#   said nothing about how to sort information, except to use the predefined
#   @c{sort} function; I have said nothing about how to store information,
#   except to use variables and lists; I have said nothing about how to write
#   programs that write programs. These are topics for another, and different
#   kind of book, a different kind of learning.
  Como he dicho, has aprendido algunos detalles; sin embargo, y muy
  importante, apenas hemos tocado aspectos importantes de la programación; no se ha
  dicho nada acerca de como clasificar la información, excepto usar la
  función predefinida @c{sort}; no he dicho nada acerca de cómo almacenar
  la información, excepto usar variables y listas; no he dicho nada
  acerca de como escribir programas que escriben programas. Esto son temas
  para otro tipo de libro, y otro tipo de aprendizaje.

#   What you have done is learn enough for much practical work with GNU Emacs.
#   What you have done is get started. This is the end of a beginning.
  Lo que has hecho es aprender lo suficiente para hacer mucho trabajo práctico
  con GNU Emacs. Lo que has hecho es comenzar. Este es el final de un comienzo.

# * Appendix A: The @c{the-the} Function
* Apéndice A: La función @c{el-el}

#   Sometimes when you you write text, you duplicate words––as with “you you”
#   near the beginning of this sentence. I find that most frequently, I
#   duplicate “the”; hence, I call the function for detecting duplicated words,
#   @c{the-the}.
  Algunas veces cuando se se escribe texto, se duplican palabras––como con “se
  se” cerca del principio de esta frase. En mi caso, encuentro que lo más
  frecuente, es duplicar “el”; por lo tanto, llamo a la función @c(el-el) para
  detectar las palabras duplicadas.

#   As a first step, you could use the following regular expression to search
#   for duplicates:
  Como primer paso, se puede utilizar la siguiente expresion regular
  para buscar duplicados:

#   ..example >
#     \\(\\w+[ \t\n]+\\)\\1
#   < example..
  ..example >
    \\(\\w+[ \t\n]+\\)\\1
  < example..

#   This regexp matches one or more word-constituent characters followed by one
#   or more spaces, tabs, or newlines. However, it does not detect duplicated
#   words on different lines, since the ending of the first word, the end of
#   the line, is different from the ending of the second word, a space.  (For
#   more information about regular expressions, see Section @l{#Regular
#   Expression Searches}, as well as Section @l{emacs.html#Regexps<>Syntax of
#   Regular Expressions} in @e(The GNU Emacs Manual), and Section
#   @l{elisp.html#Regular Expressions<>Regular Expressions} in @e{The GNU Emacs
#   Lisp Reference Manual}.)
  Esta regexp coincide con uno o más caracteres que constituyen palabras seguidas
  por uno o más espacios, tabuladores, o líneas nuevas. Sin embargo, no
  detecta palabras duplicadas en líneas diferentes, ya que el final de la
  la primer palabra, el final de la línea, es diferente del final de la
  segunda palabra, un espacio. (Para más información acerca de expresiones
  regulares, mira el Capitulo 12 @l{#Búsqueda de Expresiones Regulares}, asi
  como la Seccion @l{emacs.html#Regexps<>Sintaxis de Expresiones Regulares} en @e{El Manual
  de GNU Emacs}, y la Seccion @l{elisp.html#Regular Expressions<>Expresiones Regulares} en @e{El Manual de
  Referencia de GNU Emacs Lisp}.)

#   You might try searching just for duplicated word-constituent characters but
#   that does not work since the pattern detects doubles such as the two
#   occurrences of ‘th’ in ‘with the’.
  Puedes intentar buscar solo duplicados para caracteres consecutivos que constituyen
  palabras, pero eso no funciona, ya que el patron detecta dobles como las dos
  ocurrencias de ‘al’ en ‘igual al’.

#   Another possible regexp searches for word-constituent characters followed
#   by non-word-constituent characters, reduplicated. Here, @c{\\w+} matches
#   one or more word-constituent characters and @c{\\W*} matches zero or more
#   non-word-constituent characters.
  Otra posible regexp busca caracteres que constituyen palabras, seguido por
  caracteres que no constituyen palabras, reduplicadas. Aquí, @c{\\w+}
  coincide con uno o más caracteres que forman palabras y @c{\\W*} con
  cero o más caracteres que no forman palabras.

#   ..example >
#     \\(\\(\\w+\\)\\W*\\)\\1
#   < example..
  ..example >
    \\(\\(\\w+\\)\\W*\\)\\1
  < example..

#   Again, not useful.
  De nuevo, no es útil.

#   Here is the pattern that I use. It is not perfect, but good enough.
#   @c{\\b} matches the empty string, provided it is at the beginning or end of
#   a word; @c{[^@@ \n\t]+} matches one or more occurrences of any characters
#   that are @e{not} an @@-sign, space, newline, or tab.
  Aquí está el patrón que uso. No es perfecto, pero es lo suficientemente
  bueno. @c{\\b} coincide con la cadena vacía siempre y cuando este al
  principio o al final de una palabra; @c{[^@@ \n\t]+} coincide con una o más
  ocurrencias de cualquier caracter que @e{no} son sea el signo @@, un espacio, nueva
  línea, o tabulador.

#   ..example >
#     \\b\\([^@ \n\t]+\\)[ \n\t]+\\1\\b
#   < example..
  ..example >
    \\b\\([^@ \n\t]+\\)[ \n\t]+\\1\\b
  < example..

#   One can write more complicated expressions, but I found that this
#   expression is good enough, so I use it.
  Uno puede escribir expresiones más complicadas, pero encontre que esta
  expresión es lo suficientemente buena, así que la uso.

#   Here is the @c{the-the} function, as I include it in my @f{.emacs} file,
#   along with a handy global key binding:
  Aquí está la función @c{el-el}, tal y como la incluyo en mi fichero
  @f{.emacs}, junto con un practico atajo global:

#   ..src > elisp
  ..src > elisp
#     (defun the-the ()
    (defun el-el ()
#       "Search forward for for a duplicated word."
      "Busca hacia adelante una palabra duplicada."
#       (interactive)
      (interactive)
#       (message "Searching for for duplicated words ...")
#       (push-mark)
      (message "Buscando palabras duplicadas ...")
      (push-mark)
#       ;; This regexp is not perfect
#       ;; but is fairly good over all:
      ;; Este regexp no es perfecto
      ;; pero a pesar de todo, es bastante bueno:
#       (if (re-search-forward
#            "\\b\\([^@ \n\t]+\\)[ \n\t]+\\1\\b" nil 'move)
#           (message "Found duplicated word.")
#         (message "End of buffer")))
      (if (re-search-forward
           "\\b\\([^@ \n\t]+\\)[ \n\t]+\\1\\b" nil 'move)
          (message "Palabra duplicada encontrada.")
        (message "Fin de búfer")))

#     ;; Bind ‘the-the’ to  C-c \
#     (global-set-key "\C-c\\" 'the-the)
    ;; Asocia ‘el-el’ a  C-c \
    (global-set-key "\C-c\\" 'el-el)
#   < src..
  < src..

#   Here is test text:
  Aquí está el texto de prueba:

#   ..example >
#     one two two three four five
#     five six seven
#   < example..
  ..example >
    uno dos dos tres cuatro cinco
    cinco seis siete
  < example..

#   You can substitute the other regular expressions shown above in the
#   function definition and try each of them on this list.
  Puedes sustituir la regexp con las mostradas anteriormente y probar cada una
  de ellas en esta lista.

# * Appendix B: Handling the Kill Ring
* Apéndice B: Manejando el anillo de la muerte

#   The kill ring is a list that is transformed into a ring by the workings of
#   the @c{current-kill} function. The @c{yank} and @c{yank-pop} commands use
#   the @c{current-kill} function.
  El anillo de la muerte es una lista que se transforma en un anillo por el
  funcionamiento de la función @c{current-kill}. Los comandos @c{yank} y
  @c{yank-pop} usan la función @c{current-kill}.

#   This appendix describes the @c{current-kill} function as well as both the
#   @c{yank} and the @c{yank-pop} commands, but first, consider the workings of
#   the kill ring.
  Este apéndice describe la función @c{current-kill} asi como los comandos
  @c{yank} y @c{yank-pop}, pero primero, examinemos el funcionamiento del anillo
  de la muerte.

#   The kill ring has a default maximum length of sixty items; this number is
#   too large for an explanation. Instead, set it to four. Please evaluate
#   the following:
  El anillo de la muerte tiene una longitud maxima predeterminada de sesenta
  elementos; hacer una explicación del porque de este número quedaría demasiado
  extenso. En su lugar, pensemos qué ocurre si se establece en cuatro. Por favor,
  evalúa lo siguiente:

#   ..src > elisp
#     (setq old-kill-ring-max kill-ring-max)
#     (setq kill-ring-max 4)
#   < src..
  ..src > elisp
    (setq old-kill-ring-max kill-ring-max)
    (setq kill-ring-max 4)
  < src..

#   Then, please copy each line of the following indented example into the kill
#   ring. You may kill each line with @k{C-k} or mark it and copy it with
#   @k{M-w}.
  Despues, por favor copia cada línea del siguiente ejemplo indentado
  dentro del anillo de la muerte. Se puede cortar cada línea
  con @k{C-k} o marcarla y copiarla con @k{M-w}.

#   (In a read-only buffer, such as the @f{*info*} buffer, the kill command,
#   @k{C-k} @%c(kill-line), will not remove the text, merely copy it to the
#   kill ring. However, your machine may beep at you. Alternatively, for
#   silence, you may copy the region of each line with the
#   @k{M-w} @%c(kill-ring-save) command. You must mark each line for this command to
#   succeed, but it does not matter at which end you put point or mark.)
  (En un búfer de solo lectura, como el búfer @f{*info*}, el comando kill,
  @k{C-k} @%c(kill-line), no eliminará el texto, solamente lo copiara al anillo
  de la muerte. Sin embargo, el ordenador puede emitir un beep. Alternativamente,
  para evitarlo, se puede copiar la región de cada línea con el comando
  @k{M-w} @%c(kill-ring-save). Debes marcar cada línea para que este comando
  tenga exito, pero no importa en que extremo se coloque el punto o la marca.)

#   Please invoke the calls in order, so that five elements attempt to fill the
#   kill ring:
  Por favor, invoca las llamadas en orden, de modo que los cinco elementos
  intenten llenar el anillo de la muerte.

#   ..example >
#     first some text
#     second piece of text
#     third line
#     fourth line of text
#     fifth bit of text
#   < example..
  ..example >
    primero un poco de texto
    segundo fragmento de texto
    tercer línea
    cuarta línea de texto
    quinta parte del texto
  < example..

#   Then find the value of @c{kill-ring} by evaluating
  Luego encuentra el valor de @c{kill-ring} evaluando

#   ..example >
#     kill-ring
#   < example..
  ..example >
    kill-ring
  < example..

#   It is:
  que es:

#   ..src > elisp
#     ("fifth bit of text" "fourth line of text"
#     "third line" "second piece of text")
#   < src..
  ..src > elisp
    ("quinta parte del texto" "cuarta línea de texto"
     "tercer línea" "segundo fragmento de texto")
  < src..

#   The first element, @'{first some text}, was dropped.
  El primer elemento, @'{primero un poco de texto}, se descarto.

#   To return to the old value for the length of the kill ring, evaluate:
  Para volver al valor anterior del tamaño del kill ring, evalúa:

#   ..src > elisp
#     (setq kill-ring-max old-kill-ring-max)
#   < src..
  ..src > elisp
    (setq kill-ring-max old-kill-ring-max)
  < src..

# ** The @c{current-kill} Function
** La función @c{current-kill}

#    The @c{current-kill} function changes the element in the kill ring to
#    which @c{kill-ring-yank-pointer} points.  (Also, the @c{kill-new} function
#    sets @c{kill-ring-yank-pointer} to point to the latest element of the kill
#    ring. The @c{kill-new} function is used directly or indirectly by
#    @c{kill-append}, @c{copy-region-as-kill}, @c{kill-ring-save},
#    @c{kill-line}, and @c{kill-region}.)
   La función @c{current-kill} cambia el elemento en el anillo de la muerte al
   que apunta @c{kill-ring-yank-pointer}. (Ademas, la función @c{kill-new}
   establece @c{kill-ring-yank-pointer} para que apunte al último elemento del
   anillo de la muerte. La función @c{kill-new} se utiliza directamente o
   indirectamente en las funciones @c{kill-append}, @c{copy-region-as-kill},
   @c{kill-ring-save}, @c{kill-line}, y @c{kill-region}.)

#    The @c{current-kill} function is used by @c{yank} and by @c{yank-pop}.
#    Here is the code for @c{current-kill}:
   La función @c{current-kill} es usada por @c{yank} y por
   @c{yank-pop}. Aquí está el código para @c{current-kill}:

#    ..src > elisp
   ..src > elisp
#      (defun current-kill (n &optional do-not-move)
     (defun current-kill (n &optional do-not-move)
#        "Rotate the yanking point by N places, and then return that kill.
#      If N is zero, ‘interprogram-paste-function’ is set, and calling it
#      returns a string, then that string is added to the front of the
#      kill ring and returned as the latest kill.
#      If optional arg DO-NOT-MOVE is non-nil, then don't actually move the
#      yanking point; just return the Nth kill forward."
       "Rota el punto de pegado por N lugares, y entonces devuelve el corte.
     Si N es cero, se establece ‘interprogram-paste-function’, y si se llama
     devuelve una cadena, entonces esa cadena se añade al frente del
     anillo de la muerte y devuelve el último corte.
     Si el argumento opcional DO-NOT-MOVE no es nulo, entonces no mueve el
     punto de pegado; solo devuelve el Nth corte hacia adelante.
#        (let ((interprogram-paste (and (= n 0)
#                                       interprogram-paste-function
#                                       (funcall interprogram-paste-function))))
        (let ((interprogram-paste (and (= n 0)
                                       interprogram-paste-function
                                       (funcall interprogram-paste-function)))))
#          (if interprogram-paste
#              (progn
         (if interprogram-paste
             (progn
#                ;; Disable the interprogram cut function when we add the new
#                ;; text to the kill ring, so Emacs doesn't try to own the
#                ;; selection, with identical text.
               ;; Deshabilita la función de corte interprograma cuando se añade
               ;; el nuevo texto al anillo de la muerte, para que Emacs no intente
               ;; apropiarse de la selección con texto idéntico.
#                (let ((interprogram-cut-function nil))
#                  (kill-new interprogram-paste))
#                interprogram-paste)
               (let ((interprogram-cut-function nil))
                 (kill-new interprogram-paste))
               interprogram-paste)
#            (or kill-ring (error "Kill ring is empty"))
           (or kill-ring (error "El anillo de la muerte esta vacio"))
#            (let ((ARGth-kill-element
#                   (nthcdr (mod (- n (length kill-ring-yank-pointer))
#                                (length kill-ring))
#                           kill-ring)))
           (let ((ARGth-kill-element
                  (nthcdr (mod (- n (length kill-ring-yank-pointer))
                               (length kill-ring))
                          kill-ring)))
#              (or do-not-move
#                  (setq kill-ring-yank-pointer ARGth-kill-element))
#              (car ARGth-kill-element)))))
             (or do-not-move
                 (setq kill-ring-yank-pointer ARGth-kill-element))
             (car ARGth-kill-element)))))
#    < src..
   < src..

#    Remember also that the @c{kill-new} function sets
#    @c{kill-ring-yank-pointer} to the latest element of the kill ring, which
#    means that all the functions that call it set the value indirectly:
#    @c{kill-append}, @c{copy-region-as-kill}, @c{kill-ring-save},
#    @c{kill-line}, and @c{kill-region}.
   Recuerda también que la función @c{kill-new} asigna
   @c{kill-ring-yank-pointer} al último elemento del anillo de la muerte,
   lo que significa que todas las funciones que la llaman establecen
   el valor de forma indirecta: @c{kill-append}, @c{copy-region-as-kill},
   @c{kill-ring-save}, @c{kill-line} y @c{kill-region}.

#    Here is the line in @c{kill-new}, which is explained in Section
#    @l{#The @c{kill-new} function}.
   Aquí está la línea en @c{kill-new}, que se explica en la Seccion
   @l{#La función @c{kill-new}}.

#    ..src > elisp
#      (setq kill-ring-yank-pointer kill-ring)
#    < src..
   ..src > elisp
     (setq kill-ring-yank-pointer kill-ring)
   < src..

#    The @c{current-kill} function looks complex, but as usual, it can be
#    understood by taking it apart piece by piece. First look at it in
#    skeletal form:
   La función @c{current-kill} parece compleja, pero como de costumbre, se puede
   entender desmontandola pieza por pieza. Primero mírala en forma de esqueleto:

#    ..src > elisp
#      (defun current-kill (n &optional do-not-move)
#        "Rotate the yanking point by N places, and then return that kill."
#        (let varlist
#          body…)
#    < src..
   ..src > elisp
     (defun current-kill (n &optional do-not-move)
       "Rota el punto de pegado por N lugares, y entonces devuelve el corte.
       (let varlist
         cuerpo…)
   < src..

#    This function takes two arguments, one of which is optional. It has a
#    documentation string. It is @e{not} interactive.
   Esta función toma dos argumentos, uno de los cuales es opcional. Tiene una cadena de
   documentación. @e{No} es una función interactiva.

#    The body of the function definition is a @c{let} expression, which itself
#    has a body as well as a @c{varlist}.
   El cuerpo de la definición de función es una expresión @c{let}, que a su vez
   tiene un cuerpo asi como una @c{varlist}.

#    The @c{let} expression declares a variable that will be only usable within
#    the bounds of this function. This variable is called
#    @c{interprogram-paste} and is for copying to another program. It is not
#    for copying within this instance of GNU Emacs. Most window systems
#    provide a facility for interprogram pasting. Sadly, that facility usually
#    provides only for the last element. Most windowing systems have not
#    adopted a ring of many possibilities, even though Emacs has provided it
#    for decades.
   La expresión @c{let} declara una variable que solo será utilizable dentro de
   los limites de esta función. Esta variable se llama @c{interprogram-paste} y
   es para copiar a otro programa. No es para copiar dentro de esta instancia de
   GNU Emacs. La mayoría de los sistemas de ventanas proveen una facilidad para
   el pegado interprograma. Tristemente, esta facilidad normalmente solo provee
   el último elemento. La mayoría de los sistemas de ventanas no han adoptado un
   anillo de muchas posibilidades, a pesar de que Emacs lo ha proporcionado
   durante décadas.

#    The @c{if} expression has two parts, one if there exists
#    @c{interprogram-paste} and one if not.
   La expresión @c{if} tiene dos partes, una si existe
   @c{interprogram-paste} y otra si no.

#    Let us consider the ‘if not’ or else-part of the @c{current-kill}
#    function.  (The then-part uses the @c{kill-new} function, which we have
#    already described. See Section @l{#The @c{kill-new} function}.)
   Consideremos la parte ‘si no’ o la parte-else de la función
   @c{current-kill}. (La parte-else utiliza la función @c{kill-new}, que ya
   hemos descrito. Consulta la Seccion @l{#La función @c{kill-new}}.)

#    ..src > elisp
#      (or kill-ring (error "Kill ring is empty"))
#      (let ((ARGth-kill-element
#             (nthcdr (mod (- n (length kill-ring-yank-pointer))
#                          (length kill-ring))
#                     kill-ring)))
#        (or do-not-move
#            (setq kill-ring-yank-pointer ARGth-kill-element))
#        (car ARGth-kill-element))
#    < src..
   ..src > elisp
     (or kill-ring (error "El anillo de la muerte esta vacio"))
     (let ((ARGth-kill-element
            (nthcdr (mod (- n (length kill-ring-yank-pointer))
                         (length kill-ring))
                    kill-ring)))
       (or do-not-move
           (setq kill-ring-yank-pointer ARGth-kill-element))
       (car ARGth-kill-element))
   < src..

#    The code first checks whether the kill ring has content; otherwise it
#    signals an error.
   El código primero comprueba si el anillo de la muerte tiene
   contenido; de lo contrario, señala un error.

#    Note that the @c{or} expression is very similar to testing length with an
#    @c{if}:
   Observa que la expresión @c{or} es muy similar en longitud a una prueba con un
   @c{if}:

#    ..src > elisp
#      (if (zerop (length kill-ring))          ; if-part
#          (error "Kill ring is empty"))       ; then-part
#        ;; No else-part
#    < src..
   ..src > elisp
     (if (zerop (length kill-ring))            ; parte-if
         (error "El Kill ring está vacío"))    ; parte-then
       ;; No hay parte-else
   < src..

#    If there is not anything in the kill ring, its length must be zero and an
#    error message sent to the user: @'{Kill ring is empty}. The
#    @c{current-kill} function uses an @c{or} expression which is simpler. But
#    an @c{if} expression reminds us what goes on.
   Si no hay nada en el anillo de la muerte, su tamaño debe
   ser cero y un mensaje de error se envía al usuario: @'{El kill ring está
   vacío}. La función @c{current-kill} usa una expresión @c{or} que es mas
   simple. Pero una expresión @c{if} nos recuerda lo que ocurre.

#    This @c{if} expression uses the function @c{zerop} which returns true if
#    the value it is testing is zero. When @c{zerop} tests true, the then-part
#    of the @c{if} is evaluated. The then-part is a list starting with the
#    function @c{error}, which is a function that is similar to the @c{message}
#    function (see Section @l{#The @c{message} Function}) in that it prints a
#    one-line message in the echo area. However, in addition to printing a
#    message, @c{error} also stops evaluation of the function within which it
#    is embedded. This means that the rest of the function will not be
#    evaluated if the length of the kill ring is zero.
   Esta expresión @c{if} usa la función @c{zerop} que devuelve verdadero si el
   valor que esta probando es cero. Cuando la prueba @c{zerop} es verdadera, se
   evalúa la parte-then del @c{if}. La parte-then es una lista que comienza con
   la función @c{error}, que es una función similar a la función @c{message}
   (Consulta la Sección @l{#La Función @c{message}}) en el sentido que imprime un
   mensaje de una línea en el área de eco. Sin embargo, además de imprimir un
   mensaje, @c{error} también detiene la evaluacion de la funcion dentro de la
   cual esta embebida. Esto significa que el resto de la función no se
   evaluara si la longitud del anillo de la muerte es cero.

#    Then the @c{current-kill} function selects the element to return. The
#    selection depends on the number of places that @c{current-kill} rotates
#    and on where @c{kill-ring-yank-pointer} points.
   Entonces la función @c{current-kill} selecciona el elemento a
   devolver. La selección depende del número de lugares en los que @c{current-kill}
   rota y donde apunta @c{kill-ring-yank-pointer}.

#    Next, either the optional @c{do-not-move} argument is true or the current
#    value of @c{kill-ring-yank-pointer} is set to point to the list. Finally,
#    another expression returns the first element of the list even if the
#    @c{do-not-move} argument is true.
   A continuacion, el argumento opcional @c{do-not-move} es verdadero o el
   valor actual de @c{kill-ring-yank-pointer} se establece para apuntar a la
   lista. Finalmente, otra expresión devuelve el primer elemento de la lista
   incluso si el argumento @c{do-not-move} es verdadero.

#    In my opinion, it is slightly misleading, at least to humans, to use the
#    term ‘error’ as the name of the @c{error} function. A better term would
#    be ‘cancel’. Strictly speaking, of course, you cannot point to, much less
#    rotate a pointer to a list that has no length, so from the point of view
#    of the computer, the word ‘error’ is correct. But a human expects to
#    attempt this sort of thing, if only to find out whether the kill ring is
#    full or empty. This is an act of exploration.
   En mi opinión, es ligeramente engañoso, al menos para humanos, usar el
   término ‘error’ como el nombre de la función @c{error}. Un término mejor
   sería ‘cancelar’. Estrictamente hablando, por supuesto, no se puede apuntar,
   mucho menos rotar un puntero a una lista que no tiene longitud, por lo que
   desde el punto de vista del ordenador, la palabra ‘error’ es correcta. Pero
   un humano espera intentar este tipo de cosas, aunque solo sea para averiguar
   si el anillo de la muerte esté lleno o vacío. Esto es un acto de exploración.

#    From the human point of view, the act of exploration and discovery is not
#    necessarily an error, and therefore should not be labeled as one, even in
#    the bowels of a computer. As it is, the code in Emacs implies that a
#    human who is acting virtuously, by exploring his or her environment, is
#    making an error. This is bad. Even though the computer takes the same
#    steps as it does when there is an ‘error’, a term such as ‘cancel’ would
#    have a clearer connotation.
   Desde el punto de vista humano, el acto de exploración y descubrimiento no es
   necesariamente un error, y por lo tanto, no debe etiquetarse como tal, ni
   siquiera en las entrañas de un ordenador. Tal como estan las cosas, el codigo
   de Emacs implica que un humano que está actuando virtuosamente, explorando su
   entorno, está cometiendo un error. Esto está mal. Incluso aunque el ordenador
   tome los mismos pasos que cuando hay un ‘error’, un término como ‘cancelar’
   tendría una connotación mas clara.

#    Among other actions, the else-part of the @c{if} expression sets the value
#    of @c{kill-ring-yank-pointer} to @c{ARGth-kill-element} when the kill ring
#    has something in it and the value of @c{do-not-move} is @c{nil}.
   Entre otras acciones, la parte-else de la expresión @c{if} establece el valor
   de @c{kill-ring-yank-pointer} a @c{ARGth-kill-element} cuando el
   anillo de la muerte tiene alguna cosa dentro y el valor de
   @c{do-not-move} es @c{nil}.

#    The code looks like this:
   El código se ve asi:

#    ..src > elisp
#      (nthcdr (mod (- n (length kill-ring-yank-pointer))
#                   (length kill-ring))
#              kill-ring)))
#    < src..
   ..src > elisp
     (nthcdr (mod (- n (length kill-ring-yank-pointer))
                  (length kill-ring))
             kill-ring)))
   < src..

#    This needs some examination. Unless it is not supposed to move the
#    pointer, the @c{current-kill} function changes where
#    @c{kill-ring-yank-pointer} points. That is what the @c{(setq
#    kill-ring-yank-pointer ARGth-kill-element))} expression does. Also,
#    clearly, @c{ARGth-kill-element} is being set to be equal to some @c{cdr}
#    of the kill ring, using the @c{nthcdr} function that is described in an
#    earlier section.  (See Section @l{#@c{copy-region-as-kill}}.)  How does it
#    do this?
   Esto necesita algún examen. A menos que no se suponga mover el puntero, la
   función @c{current-kill} cambia a donde apunta @c{kill-ring-yank-pointer}.
   Esto es lo que hace la expresión @c{(setq kill-ring-yank-pointer
   ARGth-kill-element)}. También, claramente, @c{ARGth-kill-element}
   está siendo asignado para ser igual a algún @c{cdr} del anillo de la
   muerte, usando la función @c{nthcdr} que se describio en
   una sección anterior. (Consulta la Seccion @l{#@c(copy-region-as-kill)}.)  ¿Cómo
   hace esto?

#    As we have seen before (see Section @l{#@c{nthcdr}}), the @c{nthcdr}
#    function works by repeatedly taking the @c{cdr} of a list––it takes the
#    @c{cdr} of the @c{cdr} of the @c{cdr} …
   Como vimos antes (en la Sección @l{#@c(nthcdr)}), la función @c{nthcdr}
   funciona tomando repetidamente el @c{cdr} de una lista––toma el
   @c{cdr}, del @c{cdr}, del @c{cdr} …

#    The two following expressions produce the same result:
   Las dos expresiones siguientes producen el mismo resultado:

#    ..src > elisp
   ..src > elisp
#      (setq kill-ring-yank-pointer (cdr kill-ring))
     (setq kill-ring-yank-pointer (cdr kill-ring))

#      (setq kill-ring-yank-pointer (nthcdr 1 kill-ring))
     (setq kill-ring-yank-pointer (nthcdr 1 kill-ring))
#    < src..
   < src..

#    However, the @c{nthcdr} expression is more complicated. It uses the
#    @c{mod} function to determine which @c{cdr} to select.
   Sin embargo, la expresión @c{nthcdr} es más complicada. Utiliza la función
   @c{mod} para determinar que @c{cdr} seleccionar.

#    (You will remember to look at inner functions first; indeed, we will have
#    to go inside the @c{mod}.)
   (Recuerda mirar primero las funciones internas, de hecho, tendremos
   que ir dentro del @c{mod}.)

#    The @c{mod} function returns the value of its first argument modulo the
#    second; that is to say, it returns the remainder after dividing the first
#    argument by the second. The value returned has the same sign as the
#    second argument.
   La función @c{mod} devuelve el valor de su primer argumento módulo el
   segundo; es decir, devuelve el resto después de dividir el primer
   argumento por el segundo. El valor devuelto tiene el mismo signo que el
   segundo argumento.

#    Thus,
   Por lo tanto,

#    ..srci > elisp
#      > (mod 12 4)
#      0  ;; because there is no remainder
#      > (mod 13 4)
#      1
#    < srci..
   ..srci > elisp
     > (mod 12 4)
     0  ;; porque no hay resto
     > (mod 13 4)
     1
   < srci..

#    In this case, the first argument is often smaller than the second. That
#    is fine.
   En este caso, el primer argumento es con frecuencia mas pequeño que el
   segundo. Eso está bien.

#    ..srci > elisp
#      > (mod 0 4)
#      0
#      > (mod 1 4)
#      1
#    < srci..
   ..srci > elisp
     > (mod 0 4)
     0
     > (mod 1 4)
     1
   < srci..

#    We can guess what the @c{-} function does. It is like @c{+} but subtracts
#    instead of adds; the @c{-} function subtracts its second argument from its
#    first. Also, we already know what the @c{length} function does (see
#    Section @l{#Find the Length of a List: @c{length}}). It returns the length
#    of a list.
   Podemos adivinar lo que hace la función @c{-}. Es como @c{+} pero
   resta en lugar de sumar; la función @c{-} sustrae su segundo argumento
   del primero. Ademas, ya sabemos lo que hace la función @c{length}
   (Ver la Sección @l{#Descubrir la longitud de una lista: @c{length}}).
   Devuelve la longitud de una lista.

#    And @c{n} is the name of the required argument to the @c{current-kill}
#    function.
   Y @c{n} es el nombre del argumento requerido para la función
   @c{current-kill}.

#    So when the first argument to @c{nthcdr} is zero, the @c{nthcdr}
#    expression returns the whole list, as you can see by evaluating the
#    following:
   Así que cuando el primer argumento de @c{nthcdr} es cero, la expresión
   @c{nthcdr} devuelve la lista entera, como puedes ver evaluando lo
   siguiente:

#    ..src > elisp
#      ;; kill-ring-yank-pointer and kill-ring have a length of four
#      ;; and (mod (- 0 4) 4) ⇒ 0
#      (nthcdr (mod (- 0 4) 4)
#              '("fourth line of text"
#                "third line"
#                "second piece of text"
#                "first some text"))
#    < src..
   ..src > elisp
     ;; kill-ring-yank-pointer y kill-ring tienen una longitud de cuatro
     ;; and (mod (- 0 4) 4) ⇒ 0
     (nthcdr (mod (- 0 4) 4)
             '("cuarta línea de texto"
               "tercer línea"
               "segundo fragmento de texto"
               "primero un poco de texto"))
   < src..

#    When the first argument to the @c{current-kill} function is one, the
#    @c{nthcdr} expression returns the list without its first element.
   Cuando el primer argumento para la función @c{current-kill} es uno, la
   expresión @c{nthcdr} devuelve la lista sin su primer elemento.

#    ..src > elisp
#      (nthcdr (mod (- 1 4) 4)
#              '("fourth line of text"
#                "third line"
#                "second piece of text"
#                "first some text"))
#    < src..
   ..src > elisp
     (nthcdr (mod (- 1 4) 4)
             '("cuarta línea de texto"
               "tercer línea"
               "segundo fragmento de texto"
               "primero un poco de texto"))
   < src..

#    Incidentally, both @c{kill-ring} and @c{kill-ring-yank-pointer} are
#    @:{global variables}. That means that any expression in Emacs Lisp can
#    access them. They are not like the local variables set by @c{let} or like
#    the symbols in an argument list. Local variables can only be accessed
#    within the @c{let} that defines them or the function that specifies them
#    in an argument list (and within expressions called by them).
   Por cierto, tanto @c{kill-ring} y @c{kill-ring-yank-pointer} son
   @:{variables globales}. Esto significa que cualquier expresión en Emacs
   Lisp puede acceder a ellas. No son como las variables locales
   establecidas por @c{let} o como los símbolos en una lista de argumentos. Solo
   se puede acceder a las variables locales dentro del @c{let} que las define
   o la función que las especifica en una lista de argumentos (y dentro de las
   expresiones llamadas por estas).

# ** @c{yank}
** @c{yank}

#    After learning about @c{current-kill}, the code for the @c{yank} function
#    is almost easy.
   Después de aprender sobre @c{current-kill}, el código para la función
   @c{yank} es casi fácil de entender.

#    The @c{yank} function does not use the @c{kill-ring-yank-pointer} variable
#    directly. It calls @c{insert-for-yank} which calls @c{current-kill} which
#    sets the @c{kill-ring-yank-pointer} variable.
   La función @c{yank} no utiliza directamente la variable @c{kill-ring-yank-pointer}.
   Llama a @c{insert-for-yank} que llama a @c{current-kill}
   que establece la variable @c{kill-ring-yank-pointer}.

#    The code looks like this:
   El código se ve asi:

#    ..src > elisp
   ..src > elisp
#      (defun yank (&optional arg)
     (defun yank (&optional arg)
#        "Reinsert (\"paste\") the last stretch of killed text.
#      More precisely, reinsert the stretch of killed text most recently
#      killed OR yanked. Put point at end, and set mark at beginning.
#      With just \\[universal-argument] as argument, same but put point at
#      beginning (and mark at end). With argument N, reinsert the Nth most
#      recently killed stretch of killed text.
       "Reinserta (\"pega\") el último fragmento del texto cortado.
     Más concretamente, vuelve a insertar el texto cortado o pegado más reciente.
     Coloca el punto al final, y asigna la marca al principio.
     Con solo \\[universal-argument] como argumento, realiza lo mismo pero coloca el
     punto al principio (y la marca al final). Con el argumento N, reinserta
     el N fragmento más recientemente cortado.

#      When this command inserts killed text into the buffer, it honors
#      ‘yank-excluded-properties’ and ‘yank-handler’ as described in the
#      doc string for ‘insert-for-yank-1’, which see.
     Cuando este comando inserta texto dentro del búfer, respeta
     a ‘yank-excluded-properties’ y ‘yank-handler’ como describe
     la cadena de documentación de ‘insert-for-yank-1’, que ve.

#      See also the command \\[yank-pop]."
     Ver también el comando \\[yank-pop]."
#        (interactive "*P")
#        (setq yank-window-start (window-start))
       (interactive "*P")
       (setq yank-window-start (window-start))
#        ;; If we don't get all the way thru, make last-command indicate that
#        ;; for the following command.
       ;; Si no llegamos hasta el final, hace que last-command
       ;; indique esto para el siguiente comando.
#        (setq this-command t)
#        (push-mark (point))
#        (insert-for-yank (current-kill (cond
#                                        ((listp arg) 0)
#                                        ((eq arg '-) -2)
#                                        (t (1- arg)))))
       (setq this-command t)
       (push-mark (point))
       (insert-for-yank (current-kill (cond
                                       ((listp arg) 0)
                                       ((eq arg '-) -2)
                                       (t (1- arg)))))
#        (if (consp arg)
       (if (consp arg)
#            ;; This is like exchange-point-and-mark,
#            ;;     but doesn't activate the mark.
#            ;; It is cleaner to avoid activation, even though the command
#            ;; loop would deactivate the mark because we inserted text.
           ;; Esto es como exchange-point-and-mark,
           ;;     pero no activa la marca.
           ;; Es mas limpio para evitar la activación, aunque el bucle de
           ;; comandos desactivaría la marca porque insertamos texto.
#            (goto-char (prog1 (mark t)
#                         (set-marker (mark-marker) (point) (current-buffer)))))
           (goto-char (prog1 (mark t)
                        (set-marker (mark-marker) (point) (current-buffer)))))
#        ;; If we do get all the way thru, make this-command indicate that.
       ;; Si llegamos hasta el final, hace que this-command lo indique.
#        (if (eq this-command t)
#            (setq this-command 'yank))
#        nil)
       (if (eq this-command t)
           (setq this-command 'yank))
       nil)
#    < src..
   < src..

#    The key expression is @c{insert-for-yank}, which inserts the string
#    returned by @c{current-kill}, but removes some text properties from it.
   La expresión clave es @c{insert-for-yank}, que inserta la cadena devuelta
   por @c{current-kill}, pero elimina algunas propiedades de texto de la misma.

#    However, before getting to that expression, the function sets the value of
#    @c{yank-window-start} to the position returned by the @c{(window-start)}
#    expression, the position at which the display currently starts. The
#    @c{yank} function also sets @c{this-command} and pushes the mark.
   Sin embargo, antes de llegar a esa expresión, la función establece el valor de
   @c{yank-window-start} a la posición devuelta por la expresión
   @c{(window-start)}, la posición en la que la pantalla comienza actualmente. La
   función @c{yank} también asigna @c{this-command} y añade la marca.

#    After it yanks the appropriate element, if the optional argument is a
#    @c{cons} rather than a number or nothing, it puts point at beginning of
#    the yanked text and mark at its end.
   Después de pegar el elemento apropiado, si el argumento opcional es un
   @c{cons} en vez de un número o nada, coloca el punto al principio del
   texto pegado y la marca al final.

#    (The @c{prog1} function is like @c{progn} but returns the value of its
#    first argument rather than the value of its last argument. Its first
#    argument is forced to return the buffer's mark as an integer. You can see
#    the documentation for these functions by placing point over them in this
#    buffer and then typing @k{C-h f} @%c(describe-function) followed by a
#    @k{RET}; the default is the function.)
   (La función @c{prog1} es como @c{progn} pero devuelve el valor de su primer
   argumento en vez del valor de su último argumento. Su primer argumento
   fuerza devolver la marca del búfer como un entero. Puede ver la
   documentación para estas funciones colocando el punto sobre ellas en
   este búfer y presionando @k{C-h f} @%c(describe-function) seguido
   por un @k{RET}; la funcion por defecto.)

#    The last part of the function tells what to do when it succeeds.
   La última parte de la función indica que hacer cuando tiene exito.

# ** @c{yank-pop}
** @c{yank-pop}

#    After understanding @c{yank} and @c{current-kill}, you know how to
#    approach the @c{yank-pop} function. Leaving out the documentation to save
#    space, it looks like this:
   Después de entender @c{yank} y @c{current-kill}, ya sabes como acercarte
   a la función @c{yank-pop}. Dejando fuera la documentación para ahorrar
   espacio, se ve asi:

#    ..src > elisp
   ..src > elisp
#      (defun yank-pop (&optional arg)
     (defun yank-pop (&optional arg)
#        "…"
       "…"
#        (interactive "*p")
#        (if (not (eq last-command 'yank))
#            (error "Previous command was not a yank"))
       (interactive "*p")
       (if (not (eq last-command 'yank))
           (error "El comando previo no fué un yank"))
#        (setq this-command 'yank)
#        (unless arg (setq arg 1))
       (setq this-command 'yank)
       (unless arg (setq arg 1))
#        (let ((inhibit-read-only t)
#              (before (< (point) (mark t))))
#          (if before
#              (funcall (or yank-undo-function 'delete-region) (point) (mark t))
#            (funcall (or yank-undo-function 'delete-region) (mark t) (point)))
       (let ((inhibit-read-only t)
             (before (< (point) (mark t))))
         (if before
             (funcall (or yank-undo-function 'delete-region) (point) (mark t))
           (funcall (or yank-undo-function 'delete-region) (mark t) (point)))
#          (setq yank-undo-function nil)
#          (set-marker (mark-marker) (point) (current-buffer))
#          (insert-for-yank (current-kill arg))
         (setq yank-undo-function nil)
         (set-marker (mark-marker) (point) (current-buffer))
         (insert-for-yank (current-kill arg))
#          ;; Set the window start back where it was in the yank command,
#          ;; if possible.
         ;; Si es posible, vuelve a colocar el inicio de la ventana en el punto
         ;; en el que se encontraba el comando yank.
#          (set-window-start (selected-window) yank-window-start t)
#          (if before
         (set-window-start (selected-window) yank-window-start t)
         (if before
#              ;; This is like exchange-point-and-mark,
#              ;;     but doesn't activate the mark.
#              ;; It is cleaner to avoid activation, even though the command
#              ;; loop would deactivate the mark because we inserted text.
             ;; Esto es es como exchange-point-and-mark,
             ;;     pero no activa la marca.
             ;; Es mas limpio para evitar la activación, aunque el bucle de
             ;; comandos desactivaría la marca porque insertamos texto.
#              (goto-char (prog1 (mark t)
#                           (set-marker (mark-marker)
#                                       (point)
#                                       (current-buffer))))))
#        nil)
             (goto-char (prog1 (mark t)
                          (set-marker (mark-marker)
                                      (point)
                                      (current-buffer))))))
       nil)
#    < src..
   < src..

#    The function is interactive with a small @c{p} so the prefix argument is
#    processed and passed to the function. The command can only be used after
#    a previous yank; otherwise an error message is sent. This check uses the
#    variable @c{last-command} which is set by @c{yank} and is discussed
#    elsewhere.  (See Section @l{#@c{copy-region-as-kill}}.)
   La función es interactiva con una pequeña @c{p} para que el argumento del
   prefijo sea procesado y pasado a la función. El comando solo se puede
   utilizar después del yank previo; de lo contrario, se envia un mensaje de
   error. Esta comprobacion utiliza la variable @c{last-command} que se asigna
   por @c{yank} y se discute en otra parte. (Consulta la Seccion
   @l{#@c(copy-region-as-kill)}.

#    The @c{let} clause sets the variable @c{before} to true or false depending
#    whether point is before or after mark and then the region between point
#    and mark is deleted. This is the region that was just inserted by the
#    previous yank and it is this text that will be replaced.
   La cláusula @c{let} asigna la variable @c{before} a verdadero o falso
   dependiendo de si el punto está antes o después de la marca y luego se
   elimina la región entre punto y marca. Esta es la región que acaba de ser
   insertada por el yank previo y es este texto el que será reemplazado.

#    @c{funcall} calls its first argument as a function, passing remaining
#    arguments to it. The first argument is whatever the @c{or} expression
#    returns. The two remaining arguments are the positions of point and mark
#    set by the preceding @c{yank} command.
   @c{funcall} llama a su primer argumento como una función, pasando los
   argumentos restantes. El primer argumento es el que devuelve la expresión
   @c{or}. Los dos argumentos restantes son las posiciones de
   punto y marca establecidas por el comando @c{yank} anterior.

#    There is more, but that is the hardest part.
   Hay más, pero esta es la parte más dificil.

# ** The @f{ring.el} File
** El fichero @f{ring.el}

#    Interestingly, GNU Emacs posses a file called @f{ring.el} that provides
#    many of the features we just discussed. But functions such as
#    @c{kill-ring-yank-pointer} do not use this library, possibly because they
#    were written earlier.
   De manera interesante, GNU Emacs posee un fichero llamado @f{ring.el} que
   proporciona muchas de las caracteristicas que acabamos de discutir. Sin embargo,
   funciones como @c{kill-ring-yank-pointer} no utilizan esta librería,
   posiblemente porque se escribieron antes.

# * Appendix C: A Graph with Labeled Axes
* Apéndice C: Un grafico con ejes etiquetados

#   Printed axes help you understand a graph. They convey scale. In an
#   earlier chapter (see Section @l{#Readying a Graph}), we wrote the code to
#   print the body of a graph. Here we write the code for printing and
#   labeling vertical and horizontal axes, along with the body itself.
  Los ejes impresos ayudan a comprender un grafico. Para transmitir escalas. En
  un capítulo anterior (Ver Sección @l{#Preparar un grafico}), escribimos código
  para imprimir el cuerpo de un grafico. Aquí escribimos el código para imprimir
  y etiquetar los ejes horizontales y verticales, a lo largo del cuerpo en si.

#   Since insertions fill a buffer to the right and below point, the new graph
#   printing function should first print the Y or vertical axis, then the body
#   of the graph, and finally the X or horizontal axis. This sequence lays out
#   for us the contents of the function:
  Puesto que las inserciones se colocan en un búfer a la derecha y debajo del
  punto, la nueva funcion de impresion de graficos debe imprimir primero el eje
  vertical Y, luego el cuerpo del grafico, y finalmente el eje horizontal
  X. Esta secuencia nos da el contenido de la función:

#   1. Set up code.
  1. Codigo de configuracion.

#   2. Print Y axis.
  2. Imprir el eje Y.

#   3. Print body of graph.
  3. Imprir el cuerpo del grafico.

#   4. Print X axis.
  4. Imprir el eje X.


#   Here is an example of how a finished graph should look:
  He aquí un ejemplo de como se ve un grafico terminado:

#   ..example >
#     10 -
#                   *
#                   *  *
#                   *  **
#                   *  ***
#      5 -      *   *******
#             * *** *******
#             *************
#           ***************
#      1 - ****************
#          |   |    |    |
#          1   5   10   15
#   < example..
  ..example >
    10 -
                  *
                  *  *
                  *  **
                  *  ***
     5 -      *   *******
            * *** *******
            *************
          ***************
     1 - ****************
         |   |    |    |
         1   5   10   15
  < example..

#   In this graph, both the vertical and the horizontal axes are labeled with
#   numbers. However, in some graphs, the horizontal axis is time and would be
#   better labeled with months, like this:
  En este grafico, tanto el eje vertical como el horizontal se etiquetan con
  números. Sin embargo, en algunos graficos, el eje horizontal es el tiempo y
  estaría mejor etiquetarlo con meses, así:

#   ..example >
#     5 -      *
#            * ** *
#            *******
#          ********** **
#     1 - **************
#         |    ^      |
#         Jan  June   Jan
#   < example..
  ..example >
    5 -      *
           * ** *
           *******
         ********** **
    1 - **************
        |    ^      |
      Enero Junio Enero
  < example..

#   Indeed, with a little thought, we can easily come up with a variety of
#   vertical and horizontal labeling schemes. Our task could become
#   complicated. But complications breed confusion. Rather than permit this,
#   it is better choose a simple labeling scheme for our first effort, and to
#   modify or replace it later.
  De hecho, con un poco de reflexion, podemos encontrar fácilmente una variedad
  de esquemas de etiquetado vertical y horizontal. Nuestra tarea podría
  complicarse. Pero las complicaciones generan confusión. En vez de permitir
  esto, es mejor elegir un esquema de etiquetado simple para nuestro primer
  esfuerzo, y modificarlo o reemplazarlo después.

#   These considerations suggest the following outline for the @c{print-graph}
#   function:
  Estas consideraciones sugieren el siguiente esquema para la función
  @c{imprimir-grafico}:

#   ..src > elisp
#     (defun print-graph (numbers-list)
#       "documentation…"
#       (let ((height  …
#             …))
#         (print-Y-axis height … )
#         (graph-body-print numbers-list)
#         (print-X-axis … )))
#   < src..
  ..src > elisp
    (defun imprimir-grafico (lista-de-numeros)
      "documentacion…"
      (let ((altura  …
            …))
        (imprimir-eje-Y altura … )
        (imprimir-cuerpo-grafico lista-de-numeros)
        (imprimir-eje-X … )))
  < src..

#   We can work on each part of the @c{print-graph} function definition in
#   turn.
  Podemos a su vez trabajar en cada parte de la definición de la función
  @c{imprimir-grafico}.

# ** The @c{print-graph} Varlist
** La varlist de @c{imprimir-grafico}

#    In writing the @c{print-graph} function, the first task is to write the
#    varlist in the @c{let} expression.  (We will leave aside for the moment
#    any thoughts about making the function interactive or about the contents
#    of its documentation string.)
   Al escribir la función @c{imprimir-grafico}, la primera tarea es escribir la
   varlist en la expresión @c{let}. (Por el momento dejaremos de lado cualquier
   idea sobre hacer que la función sea interactiva o sobre los contenidos de su
   cadena de documentación.)

#    The varlist should set several values. Clearly, the top of the label for
#    the vertical axis must be at least the height of the graph, which means
#    that we must obtain this information here. Note that the
#    @c{print-graph-body} function also requires this information. There is no
#    reason to calculate the height of the graph in two different places, so we
#    should change @c{print-graph-body} from the way we defined it earlier to
#    take advantage of the calculation.
   La varlist debe establecer varios valores. Claramente, la parte superior de
   la etiqueta para el eje vertical debe ser al menos la altura del grafico, lo
   que significa que debemos obtener esta información aquí. Ten en cuenta que la función
   @c{imprimir-cuerpo-grafico} también requiere esta información. No hay ninguna
   razón para calcular la altura del grafico en dos lugares diferentes, por lo que
   debemos modificar @c{imprimir-cuerpo-grafico} para aprovechar el cálculo.

#    Similarly, both the function for printing the X axis labels and the
#    @c{print-graph-body} function need to learn the value of the width of each
#    symbol. We can perform the calculation here and change the definition for
#    @c{print-graph-body} from the way we defined it in the previous chapter.
   De manera similar, tanto la función para imprimir la etiqueta del eje X y la
   función @c{imprimir-cuerpo-grafico} necesita aprender el valor del ancho de
   cada símbolo. Podemos realizar el cálculo aquí y cambiar la definición de
   @c{imprimir-cuerpo-grafico} que definimos en el capítulo anterior.

#    The length of the label for the horizontal axis must be at least as long
#    as the graph. However, this information is used only in the function that
#    prints the horizontal axis, so it does not need to be calculated here.
   La longitud de la etiqueta para el eje horizontal debe ser al menos igual que
   la del grafico. Sin embargo, esta información solo se usa en la función que
   imprime el eje horizontal, por lo que no es necesario calcularla aqui.

#    These thoughts lead us directly to the following form for the varlist in
#    the @c{let} for @c{print-graph}:
   Estos pensamientos nos llevan directamente a la siguiente forma para la
   varlist en el @c{let} de @c{imprimir-grafico}:

#    ..src > elisp
#      (let ((height (apply 'max numbers-list)) ; First version.
#            (symbol-width (length graph-blank)))
#    < src..
   ..src > elisp
     (let ((altura (apply 'max lista-de-numeros)) ; Primera versión.
           (ancho-del-simbolo (length simbolo-en-blanco)))
   < src..

#    As we shall see, this expression is not quite right.
   Como veremos, esta expresión no es del todo correcta.

# ** The @c{print-Y-axis} Function
** La función @c{imprimir-eje-Y}

#    The job of the @c{print-Y-axis} function is to print a label for the
#    vertical axis that looks like this:
   El trabajo de la función @c{imprimir-eje-Y} es imprimir una etiqueta para el
   eje vertical que tenga este aspecto:

#    ..example >
   ..example >
#      10 -
     10 -




#       5 -
      5 -



#       1 -
      1 -
#    < example..
   < example..

#    The function should be passed the height of the graph, and then should
#    construct and insert the appropriate numbers and marks.
   La función debe pasarse a la altura del grafico, y luego debe construir e insertar los
   números y marcas apropiados.

#    It is easy enough to see in the figure what the Y axis label should look
#    like; but to say in words, and then to write a function definition to do
#    the job is another matter. It is not quite true to say that we want a
#    number and a tic every five lines: there are only three lines between the
#    @'{1} and the @'{5} (lines 2, 3, and 4), but four lines between the @'{5}
#    and the @'{10} (lines 6, 7, 8, and 9). It is better to say that we want a
#    number and a tic mark on the base line (number 1) and then that we want a
#    number and a tic on the fifth line from the bottom and on every line that
#    is a multiple of five.
   Es suficientemente fácil ver en la figura como deberia ser la etiqueta del
   eje Y; pero decir con palabras, y luego escribir una definición de función
   para hacer el trabajo es otro asunto. No es del todo cierto decir que
   queremos un número y una marca cada cinco líneas: solo hay tres líneas entre
   el @'{1} y el @'{5} (líneas 2, 3 y 4), pero cuatro líneas entre el @'{5} y el
   @'{10} (líneas 6, 7, 8 y 9). Es mejor decir que se quiere un número y una
   marca en la quinta línea desde la parte inferior y en cada línea que sea un
   múltiplo de cinco.

#    The next issue is what height the label should be?  Suppose the maximum
#    height of tallest column of the graph is seven. Should the highest label
#    on the Y axis be @'{5 -}, and should the graph stick up above the label?
#    Or should the highest label be @'{7 -}, and mark the peak of the graph?
#    Or should the highest label be @'{10 -}, which is a multiple of five, and
#    be higher than the topmost value of the graph?
   La siguiente cuestión es que altura debe tener la etiqueta. Supóngamos que la
   altura máxima de la columna mas alta del grafico es siete. Debe la etiqueta
   mas alta en el eje Y ser @'{5 -}, ¿y el grafico sobresalir por encima de la
   etiqueta?, ¿o la etiqueta mas alta ser @'{7 -}, y marcar el pico del grafico?
   ¿o deberia ser @'{10 -}, que es un múltiplo de cinco, y ser mas alta que el
   valor más alto del grafico?

#    The latter form is preferred. Most graphs are drawn within rectangles
#    whose sides are an integral number of steps long––5, 10, 15, and so on for
#    a step distance of five. But as soon as we decide to use a step height
#    for the vertical axis, we discover that the simple expression in the
#    varlist for computing the height is wrong. The expression is @c{(apply
#    'max numbers-list)}. This returns the precise height, not the maximum
#    height plus whatever is necessary to round up to the nearest multiple of
#    five. A more complex expression is required.
   Se prefiere esta última forma. La mayoría de los graficos se dibujan dentro
   de rectángulos cuyos lados son un número integral de pasos de longitud––5, 10,
   15, y así sucesivamente para una distancia de paso de cinco. Pero tan pronto
   como decidimos usar una altura de escalon para el eje vertical, descubrimos
   que la expresión simple en la varlist para calcular la altura es incorrecta.
   La expresión es @c{(apply 'max lista-de-numeros)}. Esto devuelve la altura
   precisa, no la altura máxima más lo que sea necesario para redondear al
   múltiplo de cinco. Se requiere una expresión más compleja.

#    As usual in cases like this, a complex problem becomes simpler if it is
#    divided into several smaller problems.
   Como es habitual en casos como este, un problema complejo se simplifica
   si se divide en varios problemas mas pequeños.

#    First, consider the case when the highest value of the graph is an
#    integral multiple of five––when it is 5, 10, 15, or some higher multiple
#    of five. We can use this value as the Y axis height.
   Primero, considere el caso cuando el valor superior del grafico es un
   múltiplo integral de cinco––cuando eso es 5, 10, 15, o algún múltiplo de
   cinco. Podemos usar este valor como la altura del eje Y.

#    A fairly simply way to determine whether a number is a multiple of five is
#    to divide it by five and see if the division results in a remainder. If
#    there is no remainder, the number is a multiple of five. Thus, seven
#    divided by five has a remainder of two, and seven is not an integral
#    multiple of five. Put in slightly different language, more reminiscent of
#    the classroom, five goes into seven once, with a remainder of two.
#    However, five goes into ten twice, with no remainder: ten is an integral
#    multiple of five.
   Una manera bastante simple para determinar si un número es múltiplo de cinco
   es dividirlo por cinco y ver si la división devuelve un resto. Si no hay
   ningun resto, el número es un múltiplo de cinco. De este modo, siete dividido
   por cinco tiene un resto de dos, y siete no es un múltiplo integral de
   cinco. Dicho de otra manera, en un lenguaje que recuerde al de un salon de
   clases, cinco se divide en siete una vez y el resto es dos. Sin embargo,
   cinco se divide en diez dos veces y no tiene resto: diez es un múltiplo
   integral de cinco.

# *** Side Trip: Compute a Remainder
*** Viaje lateral: Calcula un resto

#     In Lisp, the function for computing a remainder is @c{%}. The function
#     returns the remainder of its first argument divided by its second
#     argument. As it happens, @c{%} is a function in Emacs Lisp that you
#     cannot discover using @c{apropos}: you find nothing if you type @k{M-x
#     apropos RET remainder RET}. The only way to learn of the
#     existence of @c{%} is to read about it in a book such as this or in the
#     Emacs Lisp sources.
    En Lisp, la función para calcular un resto es @c{%}. La función devuelve el
    resto de su primer argumento dividido por su segundo argumento. Da la
    casualidad que @c{%} es una función en Emacs Lisp que no se puede
    descubrir usando @c{apropos}: no se encuentra nada al escribir @k{M-x
    apropos RET resto RET}. La unica forma de conocer la existencia de @c{%} es
    leer sobre ello en un libro como este o en las fuentes de Emacs Lisp.

#     You can try the @c{%} function by evaluating the following two
#     expressions:
    Puedes probar la función @c{%} evaluando las dos siguientes expresiones:

#     ..src > elisp
    ..src > elisp
#       (% 7 5)
      (% 7 5)

#       (% 10 5)
      (% 10 5)
#     < src..
    < src..

#     The first expression returns 2 and the second expression returns 0.
    La primer expresión devuelve 2 y la segunda 0.

#     To test whether the returned value is zero or some other number, we can
#     use the @c{zerop} function. This function returns @c{t} if its argument,
#     which must be a number, is zero.
    Para probar si el valor devuelto es cero o algún otro número, podemos
    usar la función @c{zerop}. Esta función devuelve @c{t} si su argumento
    que debe ser un número, es cero.

#     ..srci > elisp
#       > (zerop (% 7 5))
#       nil
#       > (zerop (% 10 5))
#       t
#     < srci..
    ..srci > elisp
      > (zerop (% 7 5))
      nil
      > (zerop (% 10 5))
      t
    < srci..

#     Thus, the following expression will return @c{t} if the height of the
#     graph is evenly divisible by five:
    Por lo tanto, la siguiente expresión devolverá @c{t} si la altura del
    grafico es divisible por cinco:

#     ..src > elisp
#       (zerop (% height 5))
#     < src..
    ..src > elisp
      (zerop (% altura 5))
    < src..

#     (The value of @c{height}, of course, can be found from @c{(apply 'max
#     numbers-list)}.)
    (El valor de @c{altura}, por supuesto, se puede encontrar con
    @c{(apply 'max lista-de-numeros)}.)

#     On the other hand, if the value of @c{height} is not a multiple of five,
#     we want to reset the value to the next higher multiple of five. This is
#     straightforward arithmetic using functions with which we are already
#     familiar. First, we divide the value of @c{height} by five to determine
#     how many times five goes into the number. Thus, five goes into twelve
#     twice. If we add one to this quotient and multiply by five, we will
#     obtain the value of the next multiple of five that is larger than the
#     height. Five goes into twelve twice. Add one to two, and multiply by
#     five; the result is fifteen, which is the next multiple of five that is
#     higher than twelve. The Lisp expression for this is:
    Por otro lado, si el valor de @c{altura} no es un múltiplo de cinco,
    queremos reajustar el valor al siguiente múltiplo de cinco. Esto
    es aritmética sencilla que usa funciones con las que ya estamos
    familiarizados. Primero, dividimos el valor de @c{altura} por cinco para
    determinar cuantas veces cinco entra en el número. De este modo, cinco
    entra en doce dos veces. Si agregamos uno a este cociente y lo multiplicamos
    por cinco, obtendremos el valor del siguiente múltiplo de cinco que es
    más grande que la altura. Cinco entra en doce dos veces. Se suma uno a
    dos, y se multiplica por cinco; el resultado es quince, que es el siguiente
    múltiplo de cinco que es mayor que doce. La expresión Lisp para esto es:

#     ..src > elisp
#       (* (1+ (/ height 5)) 5)
#     < src..
    ..src > elisp
      (* (1+ (/ altura 5)) 5)
    < src..

#     For example, if you evaluate the following, the result is 15:
    Por ejemplo, al evaluar lo siguiente, el resultado es 15:

#     ..src > elisp
#       (* (1+ (/ 12 5)) 5)
#     < src..
    ..src > elisp
      (* (1+ (/ 12 5)) 5)
    < src..

#     All through this discussion, we have been using ‘five’ as the value for
#     spacing labels on the Y axis; but we may want to use some other value.
#     For generality, we should replace ‘five’ with a variable to which we can
#     assign a value. The best name I can think of for this variable is
#     @c{Y-axis-label-spacing}.
    A lo largo de esta discusión, hemos estado usando ‘cinco’ como el valor de
    espaciado para las etiquetas en el eje Y; pero es posible que queramos usar
    algún otro valor. Generalmente, debemos reemplazar ‘cinco’ con una variable
    a la que podamos asignar un valor. El mejor nombre que puedo pensar para
    esta variable es @c{distancia-entre-etiquetas-del-eje-Y}.

#     Using this term, and an @c{if} expression, we produce the following:
    Usando este término, y una expresión @c{if}, producimos lo siguiente:

#     ..src > elisp
#       (if (zerop (% height Y-axis-label-spacing))
#           height
#         ;; else
#         (* (1+ (/ height Y-axis-label-spacing))
#            Y-axis-label-spacing))
#     < src..
    ..src > elisp
      (if (zerop (% altura distancia-entre-etiquetas-del-eje-Y))
          altura
        ;; else
        (* (1+ (/ altura distancia-entre-etiquetas-del-eje-Y))
           distancia-entre-etiquetas-del-eje-Y))
    < src..

#     This expression returns the value of @c{height} itself if the height is
#     an even multiple of the value of the @c{Y-axis-label-spacing} or else it
#     computes and returns a value of @c{height} that is equal to the next
#     higher multiple of the value of the @c{Y-axis-label-spacing}.
    Esta expresión devuelve el valor de la @c{altura}, bien, si la altura es
    un múltiplo del valor de la @c{distancia-entre-etiquetas-del-eje-Y} o
    realizando un calculo si el valor de @c{altura} es igual al siguiente
    múltiplo superior del valor de la @c{distancia-entre-etiquetas-del-eje-Y}.

#     We can now include this expression in the @c{let} expression of the
#     @c{print-graph} function (after first setting the value of
#     @c{Y-axis-label-spacing}):
    Ahora podemos incluir esta expresión en la expresión @c{let} de la
    función @c{imprimir-grafico} (después de establecer el valor de la
    @c{distancia-entre-etiquetas-del-eje-Y}):

#     ..src > elisp
    ..src > elisp
#       (defvar Y-axis-label-spacing 5
#         "Number of lines from one Y axis label to next.")
      (defvar distancia-entre-etiquetas-del-eje-Y 5
        "Número de líneas desde una etiqueta del eje Y a la siguiente.")

#       …
      …
#       (let* ((height (apply 'max numbers-list))
#              (height-of-top-line
#               (if (zerop (% height Y-axis-label-spacing))
#                   height
#                 ;; else
#                 (* (1+ (/ height Y-axis-label-spacing))
#                    Y-axis-label-spacing)))
#              (symbol-width (length graph-blank))))
#       …
      (let* ((altura (apply 'max lista-de-numeros))
             (altura-de-la-linea-superior
              (if (zerop (% altura distancia-entre-etiquetas-del-eje-Y))
                  altura
                ;; else
                (* (1+ (/ altura distancia-entre-etiquetas-del-eje-Y))
                   distancia-entre-etiquetas-del-eje-Y)))
             (ancho-del-simbolo (length simbolo-en-blanco))))
      …
#     < src..
    < src..

#     (Note use of the @c{let*} function: the initial value of height is
#     computed once by the @c{(apply 'max numbers-list)} expression and then
#     the resulting value of @c{height} is used to compute its final value.
#     See Section @l{#The @c{let*} expression}, for more about @c{let*}.)
    (Observa el uso de la función @c{let*}: el valor inicial de la @c{altura} se
    calcula una vez con la expresión @c{(apply 'max lista-de-numeros)} y luego
    se usa el resultado para calcular su valor final. Consulta la Seccion @l{#La
    expresión @c{let*}}, para conocer más sobre @c{let*}.)

# *** Construct a Y Axis Element
*** Construir un elemento del eje Y

#     When we print the vertical axis, we want to insert strings such as @'{5
#     - } and @'{10 - } every five lines. Moreover, we want the numbers and
#     dashes to line up, so shorter numbers must be padded with leading spaces.
#     If some of the strings use two digit numbers, the strings with single
#     digit numbers must include a leading blank space before the number.
    Cuando imprimimos el eje vertical, queremos insertar cadenas como @'{5 - } y
    @'{10 - } cada cinco líneas. Además, queremos que los números y los guiones
    se alineen, por lo que los numeros mas cortos se deben rellenar con espacios
    en blanco. Si alguna de las cadenas utiliza numeros de dos dígitos, las
    cadenas con numeros de un solo dígito deben incluir un espacio en blanco
    delante del número.

#     To figure out the length of the number, the @c{length} function is used.
#     But the @c{length} function works only with a string, not with a number.
#     So the number has to be converted from being a number to being a string.
#     This is done with the @c{number-to-string} function. For example,
    Para calcular la longitud del número, se usa la función @c{length}. Pero la
    función @c{length} solo funciona con una cadena, no con un número. Así que el
    número tiene que ser convertido de un número a una cadena. Esto se hace
    con la función @c{number-to-string}. Por ejemplo,

#     ..srci > elisp
#       > (length (number-to-string 35))
#       2
#       > (length (number-to-string 100))
#       3
#     < srci..
    ..srci > elisp
      > (length (number-to-string 35))
      2
      > (length (number-to-string 100))
      3
    < srci..

#     (@c{number-to-string} is also called @c{int-to-string}; you will see this
#     alternative name in various sources.)
    (@c{number-to-string} tambien se llama @c{int-to-string}; verás este nombre
    alternativo en varios ficheros fuente.)

#     In addition, in each label, each number is followed by a string such as
#     @'{ - }, which we will call the @c{Y-axis-tic} marker. This variable is
#     defined with @c{defvar}:
    Además, en cada etiqueta, cada número va seguido por una cadena @'{ - }, a
    la que llamaremos @c{marca-del-eje-Y}. Esta variable se define con
    @c{defvar}:

#     ..src > elisp
#       (defvar Y-axis-tic " - "
#          "String that follows number in a Y axis label.")
#     < src..
    ..src > elisp
      (defvar marca-del-eje-Y " - "
         "La Cadena que sigue al número en una etiqueta del eje Y.")
    < src..

#     The length of the Y label is the sum of the length of the Y axis tic mark
#     and the length of the number of the top of the graph.
    El tamaño de la etiqueta Y es la suma del tamaño de la marca del eje Y y el tamaño
    del número de la parte superior del grafico.

#     ..src > elisp
#       (length (concat (number-to-string height) Y-axis-tic)))
#     < src..
    ..src > elisp
      (length (concat (number-to-string altura) marca-del-eje-Y)))
    < src..

#     This value will be calculated by the @c{print-graph} function in its
#     varlist as @c{full-Y-label-width} and passed on.  (Note that we did not
#     think to include this in the varlist when we first proposed it.)
    Este valor será calculado por la función @c{imprimir-grafico} en su varlist
    como @c{ancho-completo-de-la-etiqueta-Y} y luego se pasara. (obverva que
    no pensamos incluir esto en el varlist cuando se propuso por primera vez.)

#     To make a complete vertical axis label, a tic mark is concatenated with a
#     number; and the two together may be preceded by one or more spaces
#     depending on how long the number is. The label consists of three parts:
#     the (optional) leading spaces, the number, and the tic mark. The
#     function is passed the value of the number for the specific row, and the
#     value of the width of the top line, which is calculated (just once) by
#     @c{print-graph}.
    Para hacer una etiqueta completa del eje vertical, se concatena la marca de
    etiqueta con un número; y los dos juntos pueden estar precedidos por uno o
    más espacios dependiendo de la longitud del número. La etiqueta consiste
    de tres partes: los espacios iniciales (opcionales), el número, y la
    marca. La función se pasa al valor del número para la fila específica, y
    el valor del ancho de la línea superior, que se calcula (solo una vez)
    por @c{imprimir-grafico}.

#     ..src > elisp
    ..src > elisp
#       (defun Y-axis-element (number full-Y-label-width)
      (defun elemento-del-eje-Y (numero ancho-completo-de-la-etiqueta-Y)
#         "Construct a NUMBERed label element.
        "Construye una etiqueta NUMERADA
#       A numbered element looks like this ‘  5 - ’,
#       and is padded as needed so all line up with
#       the element for the largest number."
      Un elemento numerado se parece a esto ‘  5 - ’,
      y se rellena segun sea necesario, de modo que todos se
      alineen con el elemento para el número mas grande."
#         (let* ((leading-spaces
#                (- full-Y-label-width
#                   (length
#                    (concat (number-to-string number)
#                            Y-axis-tic)))))
        (let* ((espacios-de-relleno
               (- ancho-completo-de-la-etiqueta-Y
                  (length
                   (concat (number-to-string numero)
                           marca-del-eje-Y)))))
#           (concat
#            (make-string leading-spaces ? )
#            (number-to-string number)
#            Y-axis-tic)))
          (concat
           (make-string espacios-de-relleno ? )
           (number-to-string numero)
           marca-del-eje-Y)))
#     < src..
    < src..

#     The @c{Y-axis-element} function concatenates together the leading spaces,
#     if any; the number, as a string; and the tic mark.
    La función @c{elemento-del-eje-Y} concatena juntos los espacios de relleno,
    si los hay; el número, como una cadena; y la marca de etiqueta.

#     To figure out how many leading spaces the label will need, the function
#     subtracts the actual length of the label––the length of the number plus
#     the length of the tic mark––from the desired label width.
    Para calcular cuantos espacios de relleno necesita la etiqueta, la función
    resta la longitud actual de la etiqueta––la longitud del numero más el tamaño de
    la marca––del ancho deseado para la etiqueta.

#     Blank spaces are inserted using the @c{make-string} function. This
#     function takes two arguments: the first tells it how long the string will
#     be and the second is a symbol for the character to insert, in a special
#     format. The format is a question mark followed by a blank space, like
#     this, @'c{? }. See Section @l{elisp.html#Character Type<>Character Type}
#     in @e{The GNU Emacs Lisp Reference Manual}, for a description of the
#     syntax for characters.  (Of course, you might want to replace the blank
#     space by some other character…  You know what to do.)
    Los espacios en blanco se insertan utilizando la función @c{make-string}.
    Esta función tiene dos argumentos: el primero dice cuan larga será la cadena
    y el segundo es un símbolo para el caracter a insertar, en un formato
    espcial. El formato es un signo de interrogacion seguido por un espacio en
    blanco, como este, @'c{? }. Consulta la Seccion @l{elisp.html#Character
    Type<>Tipo de Caracter} en @e{El Manual de Referencia de GNU Emacs Lisp}, para
    obtener una descripción de la sintaxis de los caracteres. (Por supuesto, es
    posible que quieras reemplazar el espacio en blanco por algún otro
    caracter…. Ya sabes qué hacer.)

#     The @c{number-to-string} function is used in the concatenation
#     expression, to convert the number to a string that is concatenated with
#     the leading spaces and the tic mark.
    La función @c{number-to-string} se utiliza en la expresión de
    concatenación, para convertir el número en una cadena que se concatena
    con los espacios de relleno y la marca de la etiqueta.

# *** Create a Y Axis Column
*** Construir una columna del eje Y

#     The preceding functions provide all the tools needed to construct a
#     function that generates a list of numbered and blank strings to insert as
#     the label for the vertical axis:
    Las funciones anteriores proporcionan todas las herramientas necesarias
    para construir una función que genere una lista de cadenas enumeradas y
    en blanco para inserta como la etiqueta del eje vertical:

#     ..src > elisp
    ..src > elisp
#       (defun Y-axis-column (height width-of-label)
      (defun columna-del-eje-Y (altura ancho-de-la-etiqueta)
#         "Construct list of Y axis labels and blank strings.
        "Construye la lista de etiquetas y cadenas en blanco del eje Y.
#       For HEIGHT of line above base and WIDTH-OF-LABEL."
      Para la ALTURA de la línea sobre la base y ANCHO-DE-LA-ETIQUETA."
#         (let (Y-axis)
#           (while (> height 1)
#             (if (zerop (% height Y-axis-label-spacing))
        (let (eje-Y)
          (while (> altura 1)
            (if (zerop (% altura distancia-entre-etiquetas-del-eje-Y))
#                 ;; Insert label.
                ;; Insertar etiqueta.
#                 (setq Y-axis
#                       (cons
#                        (Y-axis-element height width-of-label)
#                        Y-axis))
                (setq eje-Y
                      (cons
                       (elemento-del-eje-Y altura ancho-de-la-etiqueta)
                       eje-Y))
#               ;; Else, insert blanks.
              ;; de lo contrario, insertar espacios en blanco.
#               (setq Y-axis
#                     (cons
#                      (make-string width-of-label ? )
#                      Y-axis)))
              (setq eje-Y
                    (cons
                     (make-string ancho-de-la-etiqueta ? )
                     eje-Y)))
#             (setq height (1- height)))
            (setq altura (1- altura)))
#           ;; Insert base line.
          ;; Insertar línea base.
#           (setq Y-axis
#                 (cons (Y-axis-element 1 width-of-label) Y-axis))
#           (nreverse Y-axis)))
          (setq eje-Y
                (cons (elemento-del-eje-Y 1 ancho-de-la-etiqueta) eje-Y))
          (nreverse eje-Y)))
#     < src..
    < src..

#     In this function, we start with the value of @c{height} and repetitively
#     subtract one from its value. After each subtraction, we test to see
#     whether the value is an integral multiple of the
#     @c{Y-axis-label-spacing}. If it is, we construct a numbered label using
#     the @c{Y-axis-element} function; if not, we construct a blank label using
#     the @c{make-string} function. The base line consists of the number one
#     followed by a tic mark.
    En esta función, empezamos con el valor de @c{altura} y restamos
    repetitivamente uno desde su valor. Después de cada resta, comprobamos si el
    valor es un multiplo integral de la @c{distancia-entre-etiquetas-del-eje-Y}.
    Si lo es, construimos una etiqueta numerada usando la función
    @c{elemento-del-eje-Y}; si no, construimos una etiqueta en blanco usando la
    función @c{make-string}. La línea base consiste en el número uno seguido por
    una marca de etiqueta.

# *** The Not Quite Final Version of @c{print-Y-axis}
*** La versión no del todo definitiva de @c{imprimir-eje-Y}

#     The list constructed by the @c{Y-axis-column} function is passed to the
#     @c{print-Y-axis} function, which inserts the list as a column.
    La lista construida por la función @c{columna-del-eje-Y} se pasa a la
    función @c{imprimir-eje-Y}, que inserta la lista como una columna.

#     ..src > elisp
    ..src > elisp
#       (defun print-Y-axis (height full-Y-label-width)
      (defun imprimir-eje-Y (altura ancho-completo-de-la-etiqueta-Y)
#         "Insert Y axis using HEIGHT and FULL-Y-LABEL-WIDTH.
#       Height must be the maximum height of the graph.
#       Full width is the width of the highest label element."
        "Inserta el eje Y usando ALTURA y ANCHO-COMPLETO-DE-LA-ETIQUETA-Y.
      La altura debe ser la altura máxima del grafico.
      El ancho completo es el ancho del mayor elemento de la etiqueta"
#       ;; Value of height and full-Y-label-width
#       ;; are passed by ‘print-graph’.
      ;; El valor de altura y ancho-completo-de-la-etiqueta-Y
      ;; se pasan por ‘imprimir-grafico’.
#         (let ((start (point)))
#           (insert-rectangle
#            (Y-axis-column height full-Y-label-width))
        (let ((inicio (point)))
          (insert-rectangle
           (columna-del-eje-Y altura ancho-completo-de-la-etiqueta-Y))
#           ;; Place point ready for inserting graph.
          ;; Coloca el punto en posicion para inserta el grafico.
#           (goto-char start)
          (goto-char inicio)
#           ;; Move point forward by value of full-Y-label-width
#           (forward-char full-Y-label-width)))
          ;; Mueve el punto hacia adelante segun el valor de ancho-completo-de-la-etiqueta-Y
          (forward-char ancho-completo-de-la-etiqueta-Y)))
#     < src..
    < src..

#     The @c{print-Y-axis} uses the @c{insert-rectangle} function to insert the
#     Y axis labels created by the @c{Y-axis-column} function. In addition, it
#     places point at the correct position for printing the body of the graph.
    @c{imprimir-eje-Y} usa la función @c{insert-rectangle} para inserta el
    eje Y creado por la función @c{columna-del-eje-Y}. Además, coloca el
    punto en la posición correcta para imprimir el cuerpo del grafico.

#     You can test @c{print-Y-axis}:
    Puedes probar @c{imprimir-eje-Y}:

#     1. Install
    1. Instala

#        ..example >
#          Y-axis-label-spacing
#          Y-axis-tic
#          Y-axis-element
#          Y-axis-column
#          print-Y-axis
#        < example..
       ..example >
         distancia-entre-etiquetas-del-eje-Y
         marca-del-eje-Y
         elemento-del-eje-Y
         columna-del-eje-Y
         imprimir-eje-Y
       < example..

#     2. Copy the following expression:
    2. Copia la siguiente expresión:

#        ..src > elisp
#          (print-Y-axis 12 5)
#        < src..
       ..src > elisp
         (imprimir-eje-Y 12 5)
       < src..

#     3. Switch to the @f{*scratch*} buffer and place the cursor where you want
#        the axis labels to start.
    3. Cambia al búfer @f{*scratch*} y coloca el cursor donde quieras que inicien
       las etiquetas de los ejes.

#     4. Type @k{M-:} @%c(eval-expression).
    4. Presiona @k{M-:} @%c(eval-expression).

#     5. Yank the @c{graph-body-print} expression into the minibuffer with
#        @k{C-y} @%c(yank).
    5. coloca la expresión @c{imprimir-cuerpo-grafico} dentro del minibúfer con
       @k{C-y} @%c(yank).

#     6. Press @k{RET} to evaluate the expression.
    6. Presiona @k{RET} para evaluar la expresión


#     Emacs will print labels vertically, the top one being @'c{10 - }.
#     (The @c{print-graph} function will pass the value of
#     @c{height-of-top-line}, which in this case will end up as 15, thereby
#     getting rid of what might appear as a bug.)
    Emacs imprimirá las etiquetas verticalmente, siendo la parte superior @'c{10 - }.
    (La función @c{imprimir-grafico} pasará el valor de
    @c{altura-de-la-linea-superior}, que en este caso terminara en 15,
    eliminando asi lo que podria aparecer como un error.)

# ** The @c{print-X-axis} Function
** La función @c{imprimir-eje-X}

#    X axis labels are much like Y axis labels, except that the ticks are on a
#    line above the numbers. Labels should look like this:
   Las etiquetas del eje X son muy parecidas a las etiquetas del eje Y, excepto
   que las marcas estan una linea por encima de los números. Las etiquetas
   deberian verse asi:

#     ..example >
#       |   |    |    |
#       1   5   10   15
#     < example..
   ..example >
     |   |    |    |
     1   5   10   15
   < example..

#    The first tic is under the first column of the graph and is preceded by
#    several blank spaces. These spaces provide room in rows above for the Y
#    axis labels. The second, third, fourth, and subsequent ticks are all
#    spaced equally, according to the value of @c{X-axis-label-spacing}.
   La primer marca está debajo de la primer columna del grafico y va precedida por
   varios espacios en blanco. Estos espacios proporcionan espacio en las
   filas para las etiquetas del eje Y. La segunda, tercera, cuarta,
   y subsiguientes marcas estan todas espaciadas por igual, de acuerdo al valor
   de @c{distancia-entre-etiquetas-del-eje-X}.

#    The second row of the X axis consists of numbers, preceded by several
#    blank spaces and also separated according to the value of the variable
#    @c{X-axis-label-spacing}.
   La segunda fila del eje X consiste en números, precedidos por varios
   espacios en blanco y también separados de acuerdo al valor de la variable
   @c{distancia-entre-etiquetas-del-eje-X}.

#    The value of the variable @c{X-axis-label-spacing} should itself be
#    measured in units of @c{symbol-width}, since you may want to change the
#    width of the symbols that you are using to print the body of the graph
#    without changing the ways the graph is labeled.
   El valor de la variable @c{distancia-entre-etiquetas-del-eje-X} debe medirse
   en unidades de @c{ancho-del-simbolo}, ya que es posible que se desee cambiar el
   ancho de los símbolos utilizados para imprimir el cuerpo del grafico
   sin cambiar la forma en que se etiqueta el grafico.

#    The @c{print-X-axis} function is constructed in more or less the same
#    fashion as the @c{print-Y-axis} function except that it has two lines: the
#    line of tic marks and the numbers. We will write a separate function to
#    print each line and then combine them within the @c{print-X-axis}
#    function.
   La función @c{imprimir-eje-X} se constituye más o menos del mismo modo
   que la función @c{imprimir-eje-Y} excepto que tiene dos líneas: la
   línea de marcas y los números. Escribiremos una función
   separada para imprimir cada línea y luego combinarlas con la función
   @c{imprimir-eje-X}.

#    This is a three step process:
   Este es un proceso de tres pasos:

#    1. Write a function to print the X axis tic marks,
#       @c{print-X-axis-tic-line}.
   1. Escribir una función para imprimir las marcas del eje X,
      @c{imprimir-linea-de-marcas-del-eje-X}.

#    2. Write a function to print the X numbers,
#       @c{print-X-axis-numbered-line}.
   2. Escribir una función para imprimir los números X,
      @c{imprimir-linea-numerada-del-eje-X}.

#    3. Write a function to print both lines, the @c{print-X-axis} function,
#       using @c{print-X-axis-tic-line} and @c{print-X-axis-numbered-line}.
   3. Escribir una función para imprimir ambas líneas, la función
      @c{imprimir-eje-X}, usando @c{imprimir-linea-de-marcas-del-eje-X} e
      @c{imprimir-linea-numerada-del-eje-X}.

# *** X Axis Tic Marks
*** Marcas del Eje X

#     The first function should print the X axis tic marks. We must specify
#     the tic marks themselves and their spacing:
    La primera función debe imprimir las marcas de etiqueta del eje X. Debemos
    especificar las marcas en sí y su espaciado:

#      ..src > elisp
#        (defvar X-axis-label-spacing
#          (if (boundp 'graph-blank)
#              (* 5 (length graph-blank)) 5)
#          "Number of units from one X axis label to next.")
#      < src..
    ..src > elisp
      (defvar distancia-entre-etiquetas-del-eje-X
        (if (boundp 'simbolo-en-blanco)
            (* 5 (length simbolo-en-blanco)) 5)
        "Número de unidades de una etiqueta del eje X a la siguiente.")
    < src..

#     (Note that the value of @c{graph-blank} is set by another @c{defvar}.
#     The @c{boundp} predicate checks whether it has already been set;
#     @c{boundp} returns @c{nil} if it has not. If @c{graph-blank} were
#     unbound and we did not use this conditional construction, in a recent GNU
#     Emacs, we would enter the debugger and see an error message saying
#     @'c{Debugger entered--Lisp error: (void-variable graph-blank)}.)
    (Ten en cuenta que el valor de @c{simbolo-en-blanco} lo establece otro
    @c{defvar}. El predicado @c{boundp} comprueba si ya ha sido establecido;
    @c{boundp} devuelve @c{nil} si no lo ha sido. Si @c{simbolo-en-blanco} no
    hubiera sido enlazado y no usaramos esta construcción condicional,
    estrariamos el depurador y veriamos un mensaje de error diciendo @'c{Debugger
    entered--Lisp error: (void-variable simbolo-en-blanco)}

#     Here is the @c{defvar} for @c{X-axis-tic-symbol}:
    Aquí está el @c{defvar} para @c{marca-del-eje-X}:

#      ..src > elisp
#        (defvar X-axis-tic-symbol "|"
#          "String to insert to point to a column in X axis.")
#      < src..
    ..src > elisp
      (defvar marca-del-eje-X "|"
        "Cadena a insertar para apuntar a una columna en el eje X.")
    < src..

#     The goal is to make a line that looks like this:
    El objetivo es crear una línea que se vea asi:

#      ..example >
#           |   |    |    |
#      < example..
    ..example >
         |   |    |    |
    < example..

#     The first tic is indented so that it is under the first column, which is
#     indented to provide space for the Y axis labels.
    La primer marca esta indentada de manera que quede debajo de la primera
    columna, que se indenta para dejar espacio para las etiquetas del eje Y.

#     A tic element consists of the blank spaces that stretch from one tic to
#     the next plus a tic symbol. The number of blanks is determined by the
#     width of the tic symbol and the @c{X-axis-label-spacing}.
    Un elemento de marca consiste en espacios en blanco que se extienden desde
    una marca a la siguiente más el símbolo de la propia marca. El número de
    espacios en blanco se determinan por el ancho del símbolo de marca y la
    @c{distancia-entre-etiquetas-del-eje-X}.

#     The code looks like this:
    El código se ve asi:

#      ..src > elisp
#        ;;; X-axis-tic-element
#        …
#        (concat
#         (make-string
#          ;; Make a string of blanks.
#          (-  (* symbol-width X-axis-label-spacing)
#              (length X-axis-tic-symbol))
#          ? )
#         ;; Concatenate blanks with tic symbol.
#         X-axis-tic-symbol)
#        …
#      < src..
    ..src > elisp
      ;;; elemento-de-marca-del-eje-X
      …
      (concat
       (make-string
        ;; Crea una cadena de espacios en blanco.
        (-  (* ancho-del-simbolo distancia-entre-etiquetas-del-eje-X)
            (length marca-del-eje-X))
        ? )
       ;; Concatena los espacios en blanco con el símbolo de marca.
       marca-del-eje-X)
      …
    < src..

#     Next, we determine how many blanks are needed to indent the first tic
#     mark to the first column of the graph. This uses the value of
#     @c{full-Y-label-width} passed it by the @c{print-graph} function.
    A continuacion, determinamos cuantos espacios en blanco se necesitan para
    indentar la primer marca en la primera columna del grafico. Utilizamos el valor
    de @c{ancho-completo-de-la-etiqueta-Y} pasado por la función @c{imprimir-grafico}.

#     The code to make @c{X-axis-leading-spaces} looks like this:
   El código para crear @c{espacios-de-relleno-del-eje-X} se ve asi:

#      ..src > elisp
#        ;; X-axis-espacios-de-relleno
#        …
#        (make-string full-Y-label-width ? )
#        …
#      < src..
    ..src > elisp
      ;; espacios-de-relleno-del-eje-X
      …
      (make-string ancho-completo-de-la-etiqueta-Y ? )
      …
    < src..

#     We also need to determine the length of the horizontal axis, which is the
#     length of the numbers list, and the number of ticks in the horizontal
#     axis:
    También necesitamos determinar la longitud del eje horizontal, que es el
    tamaño de la lista de números, y el número de marcas del eje
    horizontal:

#      ..src > elisp
    ..src > elisp
#        ;; X-length
      ;; longitud-X
#        …
      …
#        (length numbers-list)
      (length lista-de-numeros)

#        ;; tic-width
      ;; longitud-marca
#        …
#        (* symbol-width X-axis-label-spacing)
      …
      (* ancho-del-simbolo distancia-entre-etiquetas-del-eje-X)

#        ;; number-of-X-ticks
      ;; numero-de-marcas-X
#        (if (zerop (% (X-length tic-width)))
#            (/ (X-length tic-width))
#          (1+ (/ (X-length tic-width))))
      (if (zerop (% (longitud-X longitud-marca)))
          (/ (longitud-X longitud-marca))
        (1+ (/ (longitud-X longitud-marca))))
#      < src..
    < src..

#     All this leads us directly to the function for printing the X axis tic
#     line:
    Todo esto nos lleva directamente a la función para imprimir la linea de
    marcas del eje X:

#      ..src > elisp
    ..src > elisp
#        (defun print-X-axis-tic-line
#          (number-of-X-tics X-axis-leading-spaces X-axis-tic-element)
      (defun imprimir-linea-de-marcas-del-eje-X
        (numero-de-marcas-X espacios-de-relleno-del-eje-X elemento-de-marca-del-eje-X)
#          "Print ticks for X axis."
        "Imprime marcas para el eje X."
#            (insert X-axis-leading-spaces)
#            (insert X-axis-tic-symbol)  ; Under first column.
          (insert espacios-de-relleno-del-eje-X)
          (insert marca-del-eje-X)  ; Debajo de la primer columna.
#            ;; Insert second tic in the right spot.
          ;; Inserta la segunda marca en el lugar adecuado.
#            (insert (concat
#                     (make-string
#                      (-  (* symbol-width X-axis-label-spacing)
#                          ;; Insert white space up to second tic symbol.
#                          (* 2 (length X-axis-tic-symbol)))
#                      ? )
#                     X-axis-tic-symbol))
          (insert (concat
                   (make-string
                    (-  (* ancho-del-simbolo distancia-entre-etiquetas-del-eje-X)
                        ;; Inserta el espacio en blanco al segundo símbolo de marca.
                        (* 2 (length marca-del-eje-X)))
                    ? )
                   marca-del-eje-X))
#            ;; Insert remaining ticks.
          ;; Inserta las marcas restantes.
#            (while (> number-of-X-tics 1)
#              (insert X-axis-tic-element)
#              (setq number-of-X-tics (1- number-of-X-tics))))
          (while (> numero-de-marcas-X 1)
            (insert elemento-de-marca-del-eje-X)
            (setq numero-de-marcas-X (1- numero-de-marcas-X))))
#      < src..
    < src..

#     The line of numbers is equally straightforward:
    La línea de números es igualmente sencilla:

#     First, we create a numbered element with blank spaces before each number:
    Primero, creamos un elemento numerado con espacios en blanco antes de
    cada número:

#      ..src > elisp
#        (defun X-axis-element (number)
#          "Construct a numbered X axis element."
#          (let ((leading-spaces
#                 (-  (* symbol-width X-axis-label-spacing)
#                     (length (number-to-string number)))))
#            (concat (make-string leading-spaces ? )
#                    (number-to-string number))))
#      < src..
    ..src > elisp
      (defun elemento-del-eje-X (numero)
        "Construye un elemento numerado del eje X."
        (let ((espacios-de-relleno
               (-  (* ancho-del-simbolo distancia-entre-etiquetas-del-eje-X)
                   (length (number-to-string numero)))))
          (concat (make-string espacios-de-relleno ? )
                  (number-to-string numero))))
    < src..

#     Next, we create the function to print the numbered line, starting with
#     the number “1” under the first column:
    A continuacion, creamos la función para imprimir la línea numerada,
    empezando con el número “1” para la primer columna:

#      ..src > elisp
    ..src > elisp
#        (defun print-X-axis-numbered-line
#          (number-of-X-tics X-axis-leading-spaces)
      (defun imprimir-linea-numerada-del-eje-X
        (numero-de-marcas-X espacios-de-relleno-del-eje-X)
#          "Print line of X-axis numbers"
        "Imprime linea de números del eje X"
#          (let ((number X-axis-label-spacing))
#            (insert X-axis-leading-spaces)
#            (insert "1")
#            (insert (concat
#                     (make-string
#                      ;; Insert white space up to next number.
#                      (-  (* symbol-width X-axis-label-spacing) 2)
#                      ? )
#                     (number-to-string number)))
        (let ((numero distancia-entre-etiquetas-del-eje-X))
          (insert espacios-de-relleno-del-eje-X)
          (insert "1")
          (insert (concat
                   (make-string
                    ;; Inserta espacios en blanco hasta el siguiente número.
                    (-  (* ancho-del-simbolo distancia-entre-etiquetas-del-eje-X) 2)
                    ? )
                   (number-to-string numero)))
#            ;; Insert remaining numbers.
          ;; Inserta los números restantes.
#            (setq number (+ number X-axis-label-spacing))
          (setq numero (+ numero distancia-entre-etiquetas-del-eje-X))
#            (while (> number-of-X-tics 1)
#              (insert (X-axis-element number))
#              (setq number (+ number X-axis-label-spacing))
#              (setq number-of-X-tics (1- number-of-X-tics)))))
          (while (> numero-de-marcas-X 1)
            (insert (elemento-del-eje-X numero))
            (setq numero (+ numero distancia-entre-etiquetas-del-eje-X))
            (setq numero-de-marcas-X (1- numero-de-marcas-X)))))
#      < src..
    < src..

#     Finally, we need to write the @c{print-X-axis} that uses
#     @c{print-X-axis-tic-line} and @c{print-X-axis-numbered-line}.
    Finalmente, necesitamos escribir @c{imprimir-eje-X} para usar
    @c{imprimir-linea-de-marcas-del-eje-X} e @c{imprimir-linea-numerada-del-eje-X}.

#     The function must determine the local values of the variables used by
#     both @c{print-X-axis-tic-line} and @c{print-X-axis-numbered-line}, and
#     then it must call them. Also, it must print the carriage return that
#     separates the two lines.
    La función debe determinar los valores locales de las variables utilizadas
    por @c{imprimir-linea-de-marcas-del-eje-X} e @c{imprimir-linea-numerada-del-eje-X}, y
    luego debe llamarlas. Ademas, debe imprimir el retorno de carro
    que separe las dos líneas.

#     The function consists of a varlist that specifies five local variables,
#     and calls to each of the two line printing functions:
    La función consiste de una varlist que especifica cinco variables
    locales, y llamadas a cada una de las dos funciones de impresion de líneas:

#     ..src > elisp
    ..src > elisp
#       (defun print-X-axis (numbers-list)
      (defun imprimir-eje-X (lista-de-numeros)
#         "Print X axis labels to length of NUMBERS-LIST."
        "Imprime las etiquetas del eje al tamaño de LISTA-DE-NUMEROS."
#         (let* ((leading-spaces
#                 (make-string full-Y-label-width ? ))
        (let* ((espacios-de-relleno
                (make-string ancho-completo-de-la-etiqueta-Y ? ))
#                ;; symbol-width is provided by graph-body-print
               ;; ancho-del-simbolo es provisto por imprimir-cuerpo-grafico
#                (tic-width (* symbol-width X-axis-label-spacing))
#                (X-length (length numbers-list))
#                (X-tic
#                 (concat
#                  (make-string
               (longitud-marca (* ancho-del-simbolo distancia-entre-etiquetas-del-eje-X))
               (longitud-X (length lista-de-numeros))
               (marca-X
                (concat
                 (make-string
#                   ;; Make a string of blanks.
                  ;; Crea una cadena de espacios en blanco.
#                   (-  (* symbol-width X-axis-label-spacing)
#                       (length X-axis-tic-symbol))
#                   ? )
                  (-  (* ancho-del-simbolo distancia-entre-etiquetas-del-eje-X)
                      (length marca-del-eje-X))
                  ? )
#                  ;; Concatenate blanks with tic symbol.
                 ;; Concatena espacios en blanco con el símbolo de la marca.
#                  X-axis-tic-symbol))
                 marca-del-eje-X))
#                (tic-number
#                 (if (zerop (% X-length tic-width))
#                     (/ X-length tic-width)
#                   (1+ (/ X-length tic-width)))))
               (numero-de-marcas
                (if (zerop (% longitud-X longitud-marca))
                    (/ longitud-X longitud-marca)
                  (1+ (/ longitud-X longitud-marca)))))
#            (print-X-axis-tic-line tic-number leading-spaces X-tic)
#            (insert "\n")
#            (print-X-axis-numbered-line tic-number leading-spaces)))
          (imprimir-linea-de-marcas-del-eje-X numero-de-marcas espacios-de-relleno marca-X)
          (insert "\n")
          (imprimir-linea-numerada-del-eje-X numero-de-marcas espacios-de-relleno)))
#     < src..
    < src..

#     You can test @c{print-X-axis}:
    Para probar @c{imprimir-eje-X}:

#     1. Install @c{X-axis-tic-symbol}, @c{X-axis-label-spacing},
#        @c{print-X-axis-tic-line}, as well as @c{X-axis-element},
#        @c{print-X-axis-numbered-line}, and @c{print-X-axis}.
    1. Instala @c{marca-del-eje-X}, @c{distancia-entre-etiquetas-del-eje-X},
       @c{imprimir-linea-de-marcas-del-eje-X}, tambien @c{elemento-del-eje-X},
       @c{imprimir-linea-numerada-del-eje-X}, e @c{imprimir-eje-X}.

#     2. Copy the following expression:
    2. Copia la siguiente expresión:

#        ..src > elisp
#          (progn
#           (let ((full-Y-label-width 5)
#                 (symbol-width 1))
#             (print-X-axis
#              '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16))))
#        < src..
      ..src > elisp
        (progn
         (let ((ancho-completo-de-la-etiqueta-Y 5)
               (ancho-del-simbolo 1))
           (imprimir-eje-X
            '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16))))
      < src..

#     3. Switch to the @f{*scratch*} buffer and place the cursor where you want
#        the axis labels to start.
    3. Cambia al búfer @f{*scratch*} y coloca el cursor donde quieras que comiencen
       las etiquetas del eje.

#     4. Type @k{M-:} @%c(eval-expression).
    4. Presiona @k{M-:} @%c(eval-expression).

#     5. Yank the test expression into the minibuffer with @k{C-y} @%c(yank).
    5. Pega la expresión de prueba dentro del minibuffer con @k{C-y} @%c(yank).

#     6. Press @k{RET} to evaluate the expression.
    5. Presiona @k{RET} para evaluar la expresión

#     Emacs will print the horizontal axis like this:
    Emacs imprimirá el eje horizontal así

#      ..example >
#             |   |    |    |    |
#             1   5   10   15   20
#      < example..
    ..example >
           |   |    |    |    |
           1   5   10   15   20
    < example..

# ** Printing the Whole Graph
** Imprimir el grafico completo

#    Now we are nearly ready to print the whole graph.
   Ahora estamos casi listos para imprimir el grafico completo.

#    The function to print the graph with the proper labels follows the outline
#    we created earlier (see Section @l{#Appendix C: A Graph with Labeled Axes}),
#    but with additions.
   La función para imprimir el grafico con las etiquetas apropiadas sigue el
   esquema que creamos anteriormente (Ver Sección @l{#Apéndice C: Un Grafico con Ejes
   Etiquetados}), pero con adiciones.

#    Here is the outline:
   Aquí está el esquema:

#    ..src > elisp
#      (defun print-graph (numbers-list)
#        "documentation…"
#        (let ((height  …
#              …))
#          (print-Y-axis height … )
#          (graph-body-print numbers-list)
#          (print-X-axis … )))
#    < src..
   ..src > elisp
     (defun imprimir-grafico (lista-de-numeros)
       "documentacion…"
       (let ((altura  …
             …))
         (imprimir-eje-Y altura … )
         (imprimir-cuerpo-grafico lista-de-numeros)
         (imprimir-eje-X … )))
   < src..

#    The final version is different from what we planned in two ways: first, it
#    contains additional values calculated once in the varlist; second, it
#    carries an option to specify the labels' increment per row. This latter
#    feature turns out to be essential; otherwise, a graph may have more rows
#    than fit on a display or on a sheet of paper.
   La versión final es diferente de lo que planeamos de dos maneras: primero,
   contiene valores adicionales calculados una vez en la varlist;
   segundo, tiene una opción para específicar el encremento de las etiquetas por
   fila. Esta última funcionalidad resulta esencial; de otro modo, un
   grafico puede tener más filas de las que caben en una pantalla o en una hoja de
   papel.

#    This new feature requires a change to the @c{Y-axis-column} function, to
#    add @c{vertical-step} to it. The function looks like this:
   Esta nueva caracteristica requiere un cambio a la función
   @c{columna-del-eje-Y}, para añadirle un @c{paso-vertical}. Esta
   función se ve asi:

#    ..src > elisp
   ..src > elisp
#      ;;; Final version.
     ;;; Versión Final.
#      (defun Y-axis-column
     (defun columna-del-eje-Y
#        (height width-of-label &optional vertical-step)
       (altura ancho-de-la-etiqueta &optional paso-vertical)
#        "Construct list of labels for Y axis.
#      HEIGHT is maximum height of graph.
#      WIDTH-OF-LABEL is maximum width of label.
#      VERTICAL-STEP, an option, is a positive integer
#      that specifies how much a Y axis label increments
#      for each line. For example, a step of 5 means
#      that each line is five units of the graph."
       "Construye una lista de etiquetas para el eje Y.
     ALTURA es la altura máxima del grafico.
     ANCHO-DE-LA-ETIQUETA es el ancho máximo de la etiqueta.
     PASO-VERTICAL, una opción, es un entero positivo que
     especifica cuanto se incrementa una etiqueta del eje Y en
     cada línea. Por ejemplo, un paso de 5 significa que cada
     línea es cinco unidades del grafico."
#        (let (Y-axis
#              (number-per-line (or vertical-step 1)))
       (let (eje-Y
             (numero-por-linea (or paso-vertical 1)))
#          (while (> height 1)
#            (if (zerop (% height Y-axis-label-spacing))
         (while (> altura 1)
           (if (zerop (% altura distancia-entre-etiquetas-del-eje-Y))
#                ;; Insert label.
               ;; Inserta etiqueta.
#                (setq Y-axis
#                      (cons
#                       (Y-axis-element
#                        (* height number-per-line)
#                        width-of-label)
#                       Y-axis))
               (setq eje-Y
                     (cons
                      (elemento-del-eje-Y
                       (* altura numero-por-linea)
                       ancho-de-la-etiqueta)
                      eje-Y))
#              ;; Else, insert blanks.
             ;; de otra forma, inserta espacios en blanco.
#              (setq Y-axis
#                    (cons
#                     (make-string width-of-label ? )
#                     Y-axis)))
#            (setq height (1- height)))
             (setq eje-Y
                   (cons
                    (make-string ancho-de-la-etiqueta ? )
                    eje-Y)))
           (setq altura (1- altura)))
#          ;; Insert base line.
         ;; Inserta línea base.
#          (setq Y-axis (cons (Y-axis-element
#                              (or vertical-step 1)
#                              width-of-label)
#                             Y-axis))
#          (nreverse Y-axis)))
         (setq eje-Y (cons (elemento-del-eje-Y
                             (or paso-vertical 1)
                             ancho-de-la-etiqueta)
                            eje-Y))
         (nreverse eje-Y)))
#    < src..
   < src..

#    The values for the maximum height of graph and the width of a symbol are
#    computed by @c{print-graph} in its @c{let} expression; so
#    @c{graph-body-print} must be changed to accept them.
   Los valores para la altura máxima del grafico y el ancho de un símbolo se
   calculan por medio de @c{imprimir-grafico} es su expresión @c{let}; por lo tanto,
   @c{imprimir-cuerpo-grafico} debe cambiarse para aceptarlos.

#    ..src > elisp
   ..src > elisp
#      ;;; Final version.
     ;;; Versión Final.
#      (defun graph-body-print (numbers-list height symbol-width)
     (defun imprimir-cuerpo-grafico (lista-de-numeros altura ancho-del-simbolo)
#        "Print a bar graph of the NUMBERS-LIST.
#      The numbers-list consists of the Y-axis values.
#      HEIGHT is maximum height of graph.
#      SYMBOL-WIDTH is number of each column."
       "Imprime un gráfico de barras de la LISTA-DE-NUMEROS.
     La lista-de-numeros consiste en los valores del eje Y.
     ALTURA es la altura máxima del grafico.
     ANCHO-DEL-SIMBOLO es el número de cada columna."
#        (let (from-position)
#          (while numbers-list
#            (setq from-position (point))
#            (insert-rectangle
#             (column-of-graph height (car numbers-list)))
#            (goto-char from-position)
#            (forward-char symbol-width)
       (let (desde-la-posicion)
         (while lista-de-numeros
           (setq desde-la-posicion (point))
           (insert-rectangle
            (columna-del-grafico altura (car lista-de-numeros)))
           (goto-char desde-la-posicion)
           (forward-char ancho-del-simbolo)
#            ;; Draw graph column by column.
           ;; Dibuja el grafico columna por columna.
#            (sit-for 0)
#            (setq numbers-list (cdr numbers-list)))
             (sit-for 0)
             (setq lista-de-numeros (cdr lista-de-numeros)))
#          ;; Place point for X axis labels.
         ;; Coloca el punto para las etiquetas del eje X.
#          (forward-line height)
#          (insert "\n")))
         (forward-line altura)
         (insert "\n")))
#    < src..
   < src..

#    Finally, the code for the @c{print-graph} function:
   Finalmente, el código para la función @c{imprimir-grafico}:

#    ..src > elisp
   ..src > elisp
#      ;;; Final version.
     ;;; Versión Final.
#      (defun print-graph
#        (numbers-list &optional vertical-step)
     (defun imprimir-grafico
       (lista-de-numeros &optional paso-vertical)
#        "Print labeled bar graph of the NUMBERS-LIST.
#      The numbers-list consists of the Y-axis values.
       "Imprime el gráfico de barras etiquetado de la LISTA-DE-NUMEROS.
     La lista-de-numeros consiste en los valores del eje Y.

#      Optionally, VERTICAL-STEP, a positive integer,
#      specifies how much a Y axis label increments for
#      each line. For example, a step of 5 means that
#      each row is five units."
     Opcionalmente, PASO-VERTICAL, un entero positivo, especifica cuanto
     se incrementa la etiqueta del eje Y en cada línea. Por ejemplo, un
     paso de 5 significa que cada fila tiene cinco unidades."
#        (let* ((symbol-width (length graph-blank))
       (let* ((ancho-del-simbolo (length simbolo-en-blanco))
#               ;; HEIGHT is both the largest number
#               ;; and the number with the most digits.
              ;; ALTURA es tanto el número más grande
              ;; como el número con mas digitos.
#               (height (apply 'max numbers-list))
#               (height-of-top-line
              (altura (apply 'max lista-de-numeros))
              (altura-de-la-linea-superior
#                (if (zerop (% height Y-axis-label-spacing))
#                    height
               (if (zerop (% altura distancia-entre-etiquetas-del-eje-Y))
                   altura
#                  ;; else
                 ;; else
#                  (* (1+ (/ height Y-axis-label-spacing))
#                     Y-axis-label-spacing)))
                 (* (1+ (/ altura distancia-entre-etiquetas-del-eje-Y))
                    distancia-entre-etiquetas-del-eje-Y)))
#               (vertical-step (or vertical-step 1))
#               (full-Y-label-width
#                (length
#                 (concat
#                  (number-to-string
#                   (* height-of-top-line vertical-step))
#                  Y-axis-tic))))
              (paso-vertical (or paso-vertical 1))
              (ancho-completo-de-la-etiqueta-Y
               (length
                (concat
                 (number-to-string
                  (* altura-de-la-linea-superior paso-vertical))
                 marca-del-eje-Y))))

#          (print-Y-axis
#           height-of-top-line full-Y-label-width vertical-step)
#          (graph-body-print
#           numbers-list height-of-top-line symbol-width)
#          (print-X-axis numbers-list)))
         (imprimir-eje-Y
          altura-de-la-linea-superior ancho-completo-de-la-etiqueta-Y paso-vertical)
         (imprimir-cuerpo-grafico
          lista-de-numeros altura-de-la-linea-superior ancho-del-simbolo)
         (imprimir-eje-X lista-de-numeros)))
#    < src..
   < src..

# *** Testing @c{print-graph}
*** Probando @c{imprimir-grafico}

#     We can test the @c{print-graph} function with a short list of numbers:
    Podemos probar la función @c{imprimir-grafico} con una pequeña lista de
    números:

#     1. Install the final versions of @c{Y-axis-column}, @c{graph-body-print},
#        and @c{print-graph} (in addition to the rest of the code.)
    1. Instala las versiones finales de @c{columna-del-eje-Y},
       @c{imprimir-cuerpo-grafico}, e @c{imprimir-grafico} (además del resto del código.)

#     2. Copy the following expression:
    2. Copia la siguiente expresión:

#        ..src > elisp
#          (print-graph '(3 2 5 6 7 5 3 4 6 4 3 2 1))
#        < src..
       ..src > elisp
         (imprimir-grafico '(3 2 5 6 7 5 3 4 6 4 3 2 1))
       < src..

#     3. Switch to the @f{*scratch*} buffer and place the cursor where you want
#        the axis labels to start.
    3. Cambia al búfer @f{*scratch*} y coloca el cursor donde quieras que inicien
       las etiquetas de los ejes.

#     4. Type @k{M-:} @%c(eval-expression).
    4. presiona @k{M-:} @%c(eval-expression).

#     5. Yank the test expression into the minibuffer with @k{C-y} @%c(yank).
    5. Pegua la expresión de prueba dentro del minibuffer con @k{C-y}
       @%c(yank).

#     6. Press @k{RET} to evaluate the expression.
    6. Presiona @k{RET} para evaluar la expresión


#     Emacs will print a graph that looks like this:
    Emacs imprimirá un grafico con este aspecto:

#     ..example >
    ..example >
#       10 -
      10 -


#                *
#               **   *
#        5 -   ****  *
#              **** ***
#            * *********
#            ************
#        1 - *************
               *
              **   *
       5 -   ****  *
             **** ***
           * *********
           ************
       1 - *************

#            |   |    |    |
#            1   5   10   15
           |   |    |    |
           1   5   10   15
#     < example..
    < example..



#     On the other hand, if you pass @c{print-graph} a @c{vertical-step} value
#     of 2, by evaluating this expression:
    Por otro lado, si se pasa a @c{imprimir-grafico} un valor de @c{paso-vertical}
    de 2, evaluando esta expresión:

#     ..src > elisp
#       (print-graph '(3 2 5 6 7 5 3 4 6 4 3 2 1) 2)
#     < src..
    ..src > elisp
      (imprimir-grafico '(3 2 5 6 7 5 3 4 6 4 3 2 1) 2)
    < src..

#     The graph looks like this
    El grafico tiene el siguiente aspecto:

#     ..example >
#       20 -
    ..example >
      20 -


#                *
#               **   *
#       10 -   ****  *
#              **** ***
#            * *********
#            ************
#        2 - *************
               *
              **   *
      10 -   ****  *
             **** ***
           * *********
           ************
       2 - *************

#            |   |    |    |
#            1   5   10   15
           |   |    |    |
           1   5   10   15
#     < example..
    < example..

#     (A question: is the ‘2’ on the bottom of the vertical axis a bug or a
#     feature?  If you think it is a bug, and should be a ‘1’ instead, (or even
#     a ‘0’), you can modify the sources.)
    (Una pregunta: ¿es el ‘2’ en la parte inferior del eje vertical un error o una
    caracteristica? Si crees que es un error, y deberia ser un ‘1’, (o incluso
    un ‘0’), puedes modificar el codigo.)

# *** Graphing Numbers of Words and Symbols
*** Graficar números de palabras y símbolos

#     Now for the graph for which all this code was written: a graph that shows
#     how many function definitions contain fewer than 10 words and symbols,
#     how many contain between 10 and 19 words and symbols, how many contain
#     between 20 and 29 words and symbols, and so on.
    Ahora el gráfico para el que todo este código fué escrito: un gráfico que
    muestra cuantas definiciones de función contienen menos de 10 palabras y
    símbolos, cuantas contienen entre 10 y 19, cuantas entre 20 y 29 palabras,
    y así sucesivamente.

#     This is a multi-step process. First make sure you have loaded all the
#     requisite code.
    Este es un proceso de varios pasos. Primero asegúrate que has cargado
    todo el código requerido.

#     It is a good idea to reset the value of @c{top-of-ranges} in case you
#     have set it to some different value. You can evaluate the following:
    Es una buena idea restablecer el valor de @c{cima-de-rangos} en
    caso de que lo hayas asignado a algún valor diferente. Puedes evaluar lo
    siguiente:

#     ..src > elisp
#       (setq top-of-ranges
#        '(10  20  30  40  50
#          60  70  80  90 100
#         110 120 130 140 150
#         160 170 180 190 200
#         210 220 230 240 250
#         260 270 280 290 300))
#     < src..
    ..src > elisp
      (setq cima-de-rangos
       '(10  20  30  40  50
         60  70  80  90 100
        110 120 130 140 150
        160 170 180 190 200
        210 220 230 240 250
        260 270 280 290 300))
    < src..

#     Next create a list of the number of words and symbols in each range.
    Luego crea una lista del número de palabras y símbolos en cada
    rango.

#     Evaluate the following:
    Evalúa lo siguiente:

#     ..src > elisp
#       (setq list-for-graph
#              (defuns-per-range
#                (sort
#                 (recursive-lengths-list-many-files
#                  (directory-files "/usr/local/emacs/lisp"
#                                   t ".+el$"))
#                 '<)
#                top-of-ranges))
#     < src..
    ..src > elisp
      (setq lista-para-el-grafico
             (definiciones-por-rango
               (sort
                (lista-de-longitudes-de-muchos-ficheros-recursiva
                 (directory-files "/usr/local/emacs/lisp"
                                  t ".+el$"))
                '<)
               cima-de-rangos))
    < src..

#     On my old machine, this took about an hour. It looked though 303 Lisp
#     files in my copy of Emacs version 19.23. After all that computing, the
#     @c{list-for-graph} had this value:
    En mi vieja máquina, esto tardaba una hora. Veia atraves de 303 ficheros
    Lisp en mi copia de Emacs version 19.23. Después de toda esa
    computación, @c{lista-para-el-grafico} tenía este valor:

#     ..src > elisp
#       (537 1027 955 785 594 483 349 292 224 199 166 120 116 99
#        90 80 67 48 52 45 41 33 28 26 25 20 12 28 11 13 220)
#     < src..
    ..src > elisp
      (537 1027 955 785 594 483 349 292 224 199 166 120 116 99
       90 80 67 48 52 45 41 33 28 26 25 20 12 28 11 13 220)
    < src..

#     This means that my copy of Emacs had 537 function definitions with fewer
#     than 10 words or symbols in them, 1,027 function definitions with 10 to
#     19 words or symbols in them, 955 function definitions with 20 to 29 words
#     or symbols in them, and so on.
    Esto significa que mi copia de Emacs tiene 537 definiciones de funcion con
    poco menos de 10 palabras o símbolos en ellas, 1027 definiciones con 10 a
    19 palabras o símbolos, 955 con 20 a 29, etc.

#     Clearly, just by looking at this list we can see that most function
#     definitions contain ten to thirty words and symbols.
    Claramente, con solo mirar esta lista se puede ver que la mayoría de
    definiciones de función contienen de diez a treinta palabras y símbolos.

#     Now for printing. We do not want to print a graph that is 1,030
#     lines high …  Instead, we should print a graph that is fewer than
#     twenty-five lines high. A graph that height can be displayed on almost
#     any monitor, and easily printed on a sheet of paper.
    Ahora a imprimirla. No queremos imprimir un grafico de 1030 líneas de alto
    …. En su lugar, debemos imprimir un grafico que tenga menos de venticinco líneas
    de alto. Un grafico cuya altura puede ser mostrada en casi cualquier
    monitor, e imprimirse fácilmente en una hoja de papel.

#     This means that each value in @c{list-for-graph} must be reduced to
#     one-fiftieth its present value.
    Esto significa que cada valor en @c{lista-para-el-grafico} debe reducirse a un
    quincuagesimo de su valor actual.

#     Here is a short function to do just that, using two functions we have not
#     yet seen, @c{mapcar} and @c{lambda}.
    Aquí hay una breve función para hacer exactamente eso, usando dos funciones que no
    hemos visto todavía, @c{mapcar} y @c{lambda}.

#     ..src > elisp
#       (defun one-fiftieth (full-range)
#         "Return list, each number one-fiftieth of previous."
#        (mapcar (lambda (arg) (/ arg 50)) full-range))
#     < src..
    ..src > elisp
      (defun un-cincuentavo (rango-completo)
        "Devuelve una lista con la quincuagesima parte de cada numero."
       (mapcar '(lambda (arg) (/ arg 50)) rango-completo))
    < src..

# *** A @c{lambda} Expression: Useful Anonymity
*** Una expresión @c{lambda}: Anonimato útil

#     @c{lambda} is the symbol for an anonymous function, a function without a
#     name. Every time you use an anonymous function, you need to include its
#     whole body.
    @c{lambda} es el símbolo para una función anónima, una función sin
    nombre. Cada vez que se use una función anónima, es necesario incluir
    todo su cuerpo.

#     Thus,
    De este modo,

#     ..src > elisp
#       (lambda (arg) (/ arg 50))
#     < src..
    ..src > elisp
      (lambda (arg) (/ arg 50))
    < src..

#     is a function definition that says ‘return the value resulting from
#     dividing whatever is passed to me as @c{arg} by 50’.
    es una definición de función que dice ‘devuelve el valor resultante de
    dividir lo que se pasa como @c{arg} por 50’.

#     Earlier, for example, we had a function @c{multiply-by-seven}; it
#     multiplied its argument by 7. This function is similar, except it
#     divides its argument by 50; and, it has no name. The anonymous
#     equivalent of @c{multiply-by-seven} is:
    Anteriormente, por ejemplo, teniamos una función @c{multiplicar-por-siete};
    multiplica su argumento por 7. Esta función es similar, excepto que
    divide su argumento por 50; y, no tiene nombre. El equivalente anónimo
    de @c{multiplicar-por-siete} es:

#      ..src > elisp
#        (lambda (number) (* 7 number))
#      < src..
    ..src > elisp
      (lambda (numero) (* 7 numero))
    < src..

#     (See Section @l{#The @c{defun} Special Form}.)
    (Consulta la Seccion @l{#La forma especial @c{defun}}.)

#     If we want to multiply 3 by 7, we can write:
    Si queremos multiplicar 3 por 7, podemos escribir:

#     ..art >
#       (multiply-by-seven 3)
#        \_______________/ ^
#                |         |
#             function  argument
#     < art..
    ..art >
      (multiplicar-por-siete 3)
       \___________________/ ^
                 |           |
              función    argumento
    < art..

#     This expression returns 21.
    Esta expresión devuelve 21.

#     Similarly, we can write:
    De manera similar, podemos escribir:

#     ..art >
#       ((lambda (number) (* 7 number)) 3)
#        \____________________________/ ^
#                      |                |
#             anonymous function     argument
#     < art..
    ..art >
      ((lambda (numero) (* 7 numero)) 3)
       \____________________________/ ^
                     |                |
             función anónima     argumento
    < art..

#     If we want to divide 100 by 50, we can write:
    Si queremos dividir 100 por 50, podemos escribir:

#     ..art >
#       ((lambda (arg) (/ arg 50)) 100)
#        \______________________/  \_/
#                    |              |
#           anonymous function   argument
#     < art..
    ..art >
      ((lambda (arg) (/ arg 50)) 100)
       \______________________/  \_/
                   |              |
           función anónima    argumento
    < art..

#     This expression returns 2. The 100 is passed to the function, which
#     divides that number by 50.
    Esta expresión devuelve 2. El 100 se pasa a la función, que divide
    este número por 50.

#     See Section @l{elisp.html#Lambda Expressions<>Lambda Expressions} in
#     @e{The GNU Emacs Lisp Reference Manual}, for more about @c{lambda}. Lisp
#     and lambda expressions derive from the Lambda Calculus.
     Cosulta la Seccion @l{elisp.html#Lambda Expressions<>Expresiones Lambda} en
     @e{El Manual de Referencia de GNU Emacs Lisp}, para más informacion acerca de
     @c{lambda}. Lisp y las expresiones Lambda se derivan del Cálculo Lambda.

# *** The @c{mapcar} Function
*** La función @c{mapcar}

#     @c{mapcar} is a function that calls its first argument with each element
#     of its second argument, in turn. The second argument must be a sequence.
    @c{mapcar} es una función que llama a su primer argumento con cada
    elemento de su segundo argumento. El segundo argumento debe ser una
    secuencia.

#     The @'{map} part of the name comes from the mathematical phrase, ‘mapping
#     over a domain’, meaning to apply a function to each of the elements in a
#     domain. The mathematical phrase is based on the metaphor of a surveyor
#     walking, one step at a time, over an area he is mapping. And @'{car}, of
#     course, comes from the Lisp notion of the first of a list.
    La parte @'{map} del nombre viene de la frase matemática, ‘mapeo sobre
    un dominio’, lo que significa aplicar una función a cada uno de
    los elementos en un dominio. La frase matemática se basa en la
    metáfora de un topografo que camina, un paso a la vez, sobre
    un área que está mapeando. Y @'{car}, por supuesto, proviene de la noción
    Lisp del primer elemento de una lista.

#     For example,
    Por ejemplo,

#     ..srci > elisp
#       > (mapcar '1+ '(2 4 6))
#       (3 5 7)
#     < srci..
    ..srci > elisp
      > (mapcar '1+ '(2 4 6))
      (3 5 7)
    < srci..

#     The function @c{1+} which adds one to its argument, is executed on
#     @e{each} element of the list, and a new list is returned.
    La función @c{1+} añade uno a su argumento, se ejecuta en @e{cada} elemento de
    la lista, y se devuelve una nueva lista.

#     Contrast this with @c{apply}, which applies its first argument to all the
#     remaining.  (See Section @l{#Readying a Graph}, for a explanation of
#     @c{apply}.)
    En contraste con @c{apply}, que aplica su primer argumento a todos los
    demas. (Consulta la Seccion @l{#Preparar un grafico}, para una explicación
    de @c{apply}.)

#     In the definition of @c{one-fiftieth}, the first argument is the
#     anonymous function:
    En la definición de @c{un-cincuentavo}, el primer argumento es la función
    anónima:

#     ..src > elisp
#       (lambda (arg) (/ arg 50))
#     < src..
    ..src > elisp
      (lambda (arg) (/ arg 50))
    < src..

#     and the second argument is @c{full-range}, which will be bound to
#     @c{list-for-graph}.
    y el segundo argumento es @c{rango-completo}, que será vinculado a
    @c{lista-para-el-grafico}.

#     The whole expression looks like this:
    La expresión completa se ve asi:

#     ..src > elisp
#       (mapcar (lambda (arg) (/ arg 50)) full-range))
#     < src..
    ..src > elisp
      (mapcar (lambda (arg) (/ arg 50)) rango-completo))
    < src..

#     See Section @l{elisp.html#Mapping Functions<>Mapping Functions} in @e{The
#     GNU Emacs Lisp Reference Manual}, for more about @c{mapcar}.
    Consulta la Seccion @l{elisp.html#Mapping Functions<>Mapeando Funciones} en
    @e{El Manual de Referencia de GNU Emacs Lisp}, para más informacion sobre
    @c{mapcar}.

#     Using the @c{one-fiftieth} function, we can generate a list in which each
#     element is one-fiftieth the size of the corresponding element in
#     @c{list-for-graph}.
    Usando la función @c{un-cincuentavo}, podemos generar una lista en la que
    cada elemento es un cincuentavo del tamaño del elemento correspondiente
    en la @c{lista-para-el-grafico}.

#     ..src > elisp
#       (setq fiftieth-list-for-graph
#             (one-fiftieth list-for-graph))
#     < src..
    ..src > elisp
      (setq cincuentavo-de-lista-para-el-grafico
            (un-cincuentavo lista-para-el-grafico))
    < src..

#     The resulting list looks like this:
    La lista resultante luce asi:

#     ..src > elisp
#       (10 20 19 15 11 9 6 5 4 3 3 2 2
#       1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 4)
#     < src..
    ..src > elisp
      (10 20 19 15 11 9 6 5 4 3 3 2 2
       1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 4)
    < src..

#     This, we are almost ready to print!  (We also notice the loss of
#     information: many of the higher ranges are 0, meaning that fewer than 50
#     defuns had that many words or symbols––but not necessarily meaning that
#     none had that many words or symbols.)
    ¡Ya estamos casi listos para imprimir! (También notamos la
    pérdida de información: muchos de los rangos mas altos son 0, lo que
    significa que menos de 50 funciones tenían tantas palabras o
    símbolos––pero no necesariamente significa que niguna tenía tantas
    palabras o símbolos.)

# *** Another Bug … Most Insidious
*** Otro error … más insidioso

#     I said ‘almost ready to print’!  Of course, there is a bug in the
#     @c{print-graph} function …  It has a @c{vertical-step} option, but not a
#     @c{horizontal-step} option. The @c{top-of-range} scale goes from 10 to
#     300 by tens. But the @c{print-graph} function will print only by ones.
    ¡Dije ‘casi listos para imprimir’! De acuerdo, hay un error en la
    función @c{imprimir-grafico} …. Tiene una opción @c{paso-vertical}, pero
    no una opción @c{paso-horizontal}. La escala de @c{cima-de-rango} va desde
    10 a 300 por decenas. Pero la función @c{imprimir-grafico} se imprimirá solo
    por unos.

#     This is a classic example of what some consider the most insidious type
#     of bug, the bug of omission. This is not the kind of bug you can find by
#     studying the code, for it is not in the code; it is an omitted feature.
#     Your best actions are to try your program early and often; and try to
#     arrange, as much as you can, to write code that is easy to understand and
#     easy to change. Try to be aware, whenever you can, that whatever you
#     have written, @e{will} be rewritten, if not soon, eventually. A hard
#     maxim to follow.
    Este es un ejemplo clásico de lo que algunos consideramos el tipo de error más
    insidioso, el error de omisión. Este no es el tipo de error que se
    puede encontrar estudiando el código, ya que no esta en el código; es una
    caracteristica omitida. Tus mejores acciones son probar tu programa temprano
    y con frecuencia; e intentar arreglar, tanto como se pueda, escribir
    código que sea fácil de comprender y fácil de cambiar. Intenta ser
    consciente, siempre que puedas, de que todo lo que has escrito, @e{será}
    reescrito, si no pronto, eventualmente. Una dura máxima a seguir.

#     It is the @c{print-X-axis-numbered-line} function that needs the work;
#     and then the @c{print-X-axis} and the @c{print-graph} functions need to
#     be adapted. Not much needs to be done; there is one nicety: the numbers
#     ought to line up under the tic marks. This takes a little thought.
    Es la función @c{imprimir-linea-numerada-del-eje-X} la que necesita trabajo;
    y luego hay que adaptar las funciones @c{imprimir-eje-X} e @c{imprimir-grafico}.
    No hay mucho que hacer; hay una cosa buena: los números deben
    alinearse con marcas de etiquetado. Esto requiere un poco de reflexion.

#     Here is the corrected @c{print-X-axis-numbered-line}:
    Aquí está @c{imprimir-linea-numerada-del-eje-X} corregido:

#     ..src > elisp
    ..src > elisp
#       (defun print-X-axis-numbered-line
#         (number-of-X-tics X-axis-leading-spaces
#          &optional horizontal-step)
      (defun imprimir-linea-numerada-del-eje-X
        (numero-de-marcas-X espacios-de-relleno-del-eje-X
         &optional paso-horizontal)
#         "Print line of X-axis numbers"
        "Imprime linea de números del eje X"
#         (let ((number X-axis-label-spacing)
#               (horizontal-step (or horizontal-step 1)))
#           (insert X-axis-leading-spaces)
        (let ((numero distancia-entre-etiquetas-del-eje-X)
              (paso-horizontal (or paso-horizontal 1)))
          (insert espacios-de-relleno-del-eje-X)
#           ;; Delete extra leading spaces.
          ;; Elimina espacios de relleno sobrantes.
#           (delete-char
#            (- (1-
#                (length (number-to-string horizontal-step)))))
#           (insert (concat
#                    (make-string
          (delete-char
           (- (1-
               (length (number-to-string paso-horizontal)))))
          (insert (concat
                   (make-string
#                     ;; Insert white space.
                    ;; Inserta espacio en blanco.
#                     (-  (* symbol-width
#                            X-axis-label-spacing)
#                         (1-
#                          (length
#                           (number-to-string horizontal-step)))
#                         2)
#                     ? )
                    (-  (* ancho-del-simbolo
                           distancia-entre-etiquetas-del-eje-X)
                        (1-
                         (length
                          (number-to-string paso-horizontal)))
                        2)
                    ? )
#                    (number-to-string
#                     (* number horizontal-step))))
                   (number-to-string
                    (* numero paso-horizontal))))
#           ;; Insert remaining numbers.
          ;; Inserta los números restantes.
#           (setq number (+ number X-axis-label-spacing))
#           (while (> number-of-X-tics 1)
#             (insert (X-axis-element
#                      (* number horizontal-step)))
#             (setq number (+ number X-axis-label-spacing))
#             (setq number-of-X-tics (1- number-of-X-tics)))))
          (setq numero (+ numero distancia-entre-etiquetas-del-eje-X))
          (while (> numero-de-marcas-X 1)
            (insert (elemento-del-eje-X
                     (* numero paso-horizontal)))
            (setq numero (+ numero distancia-entre-etiquetas-del-eje-X))
            (setq numero-de-marcas-X (1- numero-de-marcas-X)))))
#     < src..
    < src..

#     If you are reading this in Info, you can see the new versions of
#     @c{print-X-axis} @c{print-graph} and evaluate them. If you are reading
#     this in a printed book, you can see the changed lines here (the full text
#     is too much to print).
    A continuacion, las líneas que cambian en @c{imprimir-eje-X} e
    @c{imprimir-grafico}.

#     ..src > elisp
    ..src > elisp
#       (defun print-X-axis (numbers-list horizontal-step)
#         …
#           (print-X-axis-numbered-line
#            tic-number leading-spaces horizontal-step))
      (defun imprimir-eje-X (lista-de-numeros paso-horizontal)
        …
          (imprimir-linea-numerada-del-eje-X
           numero-de-marcas espacios-de-relleno paso-horizontal))

#       (defun print-graph
#         (numbers-list
#          &optional vertical-step horizontal-step)
#         …
#           (print-X-axis numbers-list horizontal-step))
      (defun imprimir-grafico
        (lista-de-numeros
         &optional paso-vertical paso-horizontal)
        …
          (imprimir-eje-X lista-de-numeros paso-horizontal))
#     < src..
    < src..

# *** The Printed Graph
*** El gráfico impreso

#     When made and installed, you can call the @c{print-graph} command like
#     this:
    Cuando está hecho e instalado, puedes llamar al comando
    @c{imprimir-grafico} asi:

#      ..src > elisp
#        (print-graph fiftieth-list-for-graph 50 10)
#      < src..
    ..src > elisp
      (imprimir-grafico cincuentavo-de-lista-para-el-grafico 50 10)
    < src..

#     Here is the graph:
    Aquí está el gráfico:

#     ..example >
#       1000 -  *
#               **
#               **
#               **
#               **
#        750 -  ***
#               ***
#               ***
#               ***
#               ****
#        500 - *****
#              ******
#              ******
#              ******
#              *******
#        250 - ********
#              *********                     *
#              ***********                   *
#              *************                 *
#         50 - ***************** *           *
#              |   |    |    |    |    |    |    |
#             10  50  100  150  200  250  300  350
#     < example..
    ..example >
      1000 -  *
              **
              **
              **
              **
       750 -  ***
              ***
              ***
              ***
              ****
       500 - *****
             ******
             ******
             ******
             *******
       250 - ********
             *********                     *
             ***********                   *
             *************                 *
        50 - ***************** *           *
             |   |    |    |    |    |    |    |
            10  50  100  150  200  250  300  350
    < example..


#     The largest group of functions contain 10--19 words and symbols each.
    El grupo mas grande de funciones contienen de 10 a 19 palabras y símbolos.

# * Appendix D: Free Software and Free Manuals @%b(by Richard M. Stallman)
* Apéndice D: Software Libre y Manuales Libres @%b{por Richard M. Stallman}

#   The biggest deficiency in free operating systems is not in the software––it
#   is the lack of good free manuals that we can include in these systems.
#   Many of our most important programs do not come with full manuals.
#   Documentation is an essential part of any software package; when an
#   important free software package does not come with a free manual, that is a
#   major gap. We have many such gaps today.
  La mayor deficiencia de los sistemas operativos libres no está en el
  software––sino en la falta de buenos manuales libres que podamos incluir en
  estos sistemas. Muchos de nuestros programas más importantes no vienen con
  manuales completos. La documentación es una parte esencial de cualquier
  paquete de software; cuando un paquete de software libre no viene con un
  manual libre, eso es un gran vacio. Hoy en dia tenemos muchos vacios de este tipo.

#   Once upon a time, many years ago, I thought I would learn Perl. I got a
#   copy of a free manual, but I found it hard to read. When I asked Perl
#   users about alternatives, they told me that there were better introductory
#   manuals––but those were not free.
  Érase una vez, hace muchos años, que pense que aprendería Perl. Consegui
  una copia de un manual libre, pero me resulto difícil de leer. Cuando
  pregunte a los usuarios de Perl sobre alternativas, me dijeron que
  habia mejores manuales introductorios––pero estos no eran libres.

#   Why was this?  The authors of the good manuals had written them for
#   O'Reilly Associates, which published them with restrictive terms––no
#   copying, no modification, source files not available––which exclude them
#   from the free software community.
  ¿Por qué fue asi? Los autores de los buenos manuales los habían escrito
  para O'Reilly Associates, que los publicaron con términos restrictivos––sin
  copia, sin modificacion, sin ficheros fuente disponibles––que los
  excluyen de la comunidad del software libre.

#   That wasn't the first time this sort of thing has happened, and (to our
#   community's great loss) it was far from the last. Proprietary manual
#   publishers have enticed a great many authors to restrict their manuals
#   since then. Many times I have heard a GNU user eagerly tell me about a
#   manual that he is writing, with which he expects to help the GNU
#   project––and then had my hopes dashed, as he proceeded to explain that he
#   had signed a contract with a publisher that would restrict it so that we
#   cannot use it.
  No era la primera vez que ocurrían estas cosas, y para nuestra comunidad es
  una gran pérdida que estaba lejos de ser la ultima. Las editoriales de
  manuales privativos han logrado que muchos autores restrinjan sus manuales
  desde entonces. Muchas veces he oido a un habil usuario de GNU hablarme con
  entusiasmo de un manual que está escribiendo, con el que espera ayudar al
  proyecto GNU––y luego mis esperanzas se vieron frustradas, mientras procedia
  a explicarme que habia firmado un contrato con una editorial que
  lo restringiría para que no pudieramos usarlo.

#   Given that writing good English is a rare skill among programmers, we can
#   ill afford to lose manuals this way.
  Debido a que escribir buen inglés es una habilidad poco comun entre los
  programadores, no podemos darnos el lujo de perder manuales de esta manera.

#   Free documentation, like free software, is a matter of freedom, not price.
#   The problem with these manuals was not that O'Reilly Associates charged a
#   price for printed copies––that in itself is fine. The Free Software
#   Foundation @l{http://shop.fsf.org<>sells printed copies} of free
#   @l{http://www.gnu.org/doc/doc.html<>GNU manuals}, too. But GNU manuals are
#   available in source code form, while these manuals are available only on
#   paper. GNU manuals come with permission to copy and modify; the Perl
#   manuals do not. These restrictions are the problems.
  La documentación, como el software, es una cuestión de libertad, no de
  precio. El problema con estos manuales no eran que O'Reilly Associates
  impusiera un precio por las copias impresas––eso en si mismo esta bien. La
  Free Software Foundation tambien @l{http://shop.fsf.org<>vende copias impresas} de los
  @l{http://www.gnu.org/doc/doc.html<>manuales libres de GNU}. Pero los
  manuales de GNU están disponibles en forma de código fuente, mientras que
  estos manuales están disponibles solo en papel. Los manuales de GNU vienen con
  permiso para copiar y modificar; los manuales de Perl no. Estas restricciones
  son un problema.

#   The criterion for a free manual is pretty much the same as for free
#   software: it is a matter of giving all users certain freedoms.
#   Redistribution (including commercial redistribution) must be permitted, so
#   that the manual can accompany every copy of the program, on-line or on
#   paper. Permission for modification is crucial too.
  El criterio para un manual libre es practicamente el mismo que para el
  software libre: es una cuestión de dar a todos los usuarios ciertas
  libertades. Se debe permitir la redistribución (incluida la redistribución
  comercial), de modo que el manual puede acompañar cada copia del programa, en linea o
  en papel. El permiso para la modificacion tambien es crucial.

#   As a general rule, I don't believe that it is essential for people to have
#   permission to modify all sorts of articles and books. The issues for
#   writings are not necessarily the same as those for software. For example,
#   I don't think you or I are obliged to give permission to modify articles
#   like this one, which describe our actions and our views.
  Como regla general, no creo que sea esencial que la gente tenga permiso para
  modificar todo tipo de artículos y libros. Las cuestiones relativa a los
  escritos no son necesariamente las mismas que las del software. Por ejemplo,
  no creo que usted o yo estemos obligados a dar permisos para modificar artículos como
  este, que describen nuestras acciones y nuestros puntos de vista.

#   But there is a particular reason why the freedom to modify is crucial for
#   documentation for free software. When people exercise their right to
#   modify the software, and add or change its features, if they are
#   conscientious they will change the manual too––so they can provide accurate
#   and usable documentation with the modified program. A manual which forbids
#   programmers to be conscientious and finish the job, or more precisely
#   requires them to write a new manual from scratch if they change the
#   program, does not fill our community's needs.
  Pero hay una razón particular por la qué la libertad de modificar es
  crucial para la documentación del software libre. Cuando las personas
  ejercen su derecho a modificar el software, y añadir o cambiar sus
  funcionalidades, si son concienzudos, tambien cambiarán el manual––de
  modo que puedan proporcionar documentación precisa y usable con el programa
  modificado. Un manual que prohibe a los programadores ser concienzudos y
  terminar el trabajo, o más precisamente requiere que escriban un nuevo manual
  desde cero si cambian el programa, no se ajusta a las necesidades de
  nuestra comunidad.

#   While a blanket prohibition on modification is unacceptable, some kinds of
#   limits on the method of modification pose no problem. For example,
#   requirements to preserve the original author's copyright notice, the
#   distribution terms, or the list of authors, are ok. It is also no problem
#   to require modified versions to include notice that they were modified,
#   even to have entire sections that may not be deleted or changed, as long as
#   these sections deal with nontechnical topics.  (Some GNU manuals have
#   them.)
  Si bien una prohibicion general de la modificación es inaceptable, algunos
  tipos de límites sobre el método de modificacion no plantea ningun
  problema. Por ejemplo, los requisitos para preservar el aviso de copyright del
  autor original, los términos de distribución, o la lista de autores, estén
  bien. Tampoco es un problemas requerir que las versiones modificadas
  incluyan un aviso de que fueron modificadas, incluso para tener secciones enteras que
  no pueden ser eliminadas o cambiadas, siempre y cuando estas secciones traten
  asuntos no técnicos. (Algunos manuales de GNU los tienen.)

#   These kinds of restrictions are not a problem because, as a practical
#   matter, they don't stop the conscientious programmer from adapting the
#   manual to fit the modified program. In other words, they don't block the
#   free software community from making full use of the manual.
  Este tipo de restricciones no son un problema porque, en la
  práctica, no impiden que el programador concienzudo adapte el manual
  al programa modificado. En otras palabras, no impiden que la
  comunidad del software libre haga pleno uso del manual.

#   However, it must be possible to modify all the technical content of the
#   manual, and then distribute the result in all the usual media, through all
#   the usual channels; otherwise, the restrictions do block the community, the
#   manual is not free, and so we need another manual.
  Sin embargo, debe ser posible modificar todo el contenido técnico del
  manual, y luego distribuir el resultado en todos los medios habituales,
  a través de todos los canales; de otro modo, las restricciones
  bloquean la comunidad, el manual no es libre, por lo que necesitamos otro
  manual.

#   Unfortunately, it is often hard to find someone to write another manual
#   when a proprietary manual exists. The obstacle is that many users think
#   that a proprietary manual is good enough––so they don't see the need to
#   write a free manual. They do not see that the free operating system has a
#   gap that needs filling.
  Desafortunadamente, con frecuencia es dificil encontrar a alguien que escriba
  otro manual cuando existe el privativo. El obstáculo es que muchos usuarios
  piensan que un manual privativo es lo suficientemente bueno––por lo que no ven
  la necesidad de escribir un manual libre. Ellos no ven que el sistema
  operativo tiene un hueco que necesita se llenado.

#   Why do users think that proprietary manuals are good enough? Some have not
#   considered the issue. I hope this article will do something to change
#   that.
  ¿Por qué los usuarios piensan que los manuales privativos son lo
  suficientemente buenos? Algunos no han considerado el tema. Espero que
  este artículo haga algo para cambiar eso.

#   Other users consider proprietary manuals acceptable for the same reason so
#   many people consider proprietary software acceptable: they judge in purely
#   practical terms, not using freedom as a criterion. These people are
#   entitled to their opinions, but since those opinions spring from values
#   which do not include freedom, they are no guide for those of us who do
#   value freedom.
  Otros usuarios considera que los manuales privativos son aceptables por la
  misma razón que muchas personas consideran que el software privativo es
  aceptable: juzgan en términos puramente prácticos, sin usar la libertad
  como criterio. Estas personas tiene derecho a sus opiniones, pero como esas
  opiniones provienen de valores que no incluyen la libertad, no son una guia
  para aquellos de nosotros que valoramos la libertad.

#   Please spread the word about this issue. We continue to lose manuals to
#   proprietary publishing. If we spread the word that proprietary manuals are
#   not sufficient, perhaps the next person who wants to help GNU by writing
#   documentation will realize, before it is too late, that he must above all
#   make it free.
  Por favor, haga correr la voz sobre este tema. Seguimos perdiendo manuales
  debido a la publicacion privativa. Si hacemos correr la voz de que los manuales
  privativos no son suficientes, quizás la siguiente persona que quiera ayudar a
  GNU escribiendo documentación se dara cuenta, antes de que sea demasiado
  tarde, que sobre todo debe hacerlo libre.

#   We can also encourage commercial publishers to sell free, copylefted
#   manuals instead of proprietary ones. One way you can help this is to check
#   the distribution terms of a manual before you buy it, and prefer copylefted
#   manuals to non-copylefted ones.
  También podemos animar a las editoriales comerciales a vender manuales libres
  o con copyleft en lugar de manuales privativos. Una forma de ayudar es
  comprobar los términos de distribución de un manual antes de comprarlo, y
  preferir manuales con copyleft a los no copyleft.

#   Note: The Free Software Foundation maintains a page on its Web site that
#   lists free books available from other publishers:
#   @l{http://www.gnu.org/doc/other-free-books.html}
  Nota: La Free Software Foundation mantiene una página en su sitio
  Web que lista libros libres disponibles en otras editoriales:
  @l{http://www.gnu.org/doc/other-free-books.html}

# * Appendix E: GNU Free Documentation License
* Appendix E: GNU Free Documentation License

#   ..center >
#     Version 1.3, 3 November 2008
#   < center..
  ..center >
    Version 1.3, 3 November 2008
  < center..

#   Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
#   <@l(http://fsf.org/)>
  Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
  <@l(http://fsf.org/)>

#   Everyone is permitted to copy and distribute verbatim copies of this
#   license document, but changing it is not allowed.
  Everyone is permitted to copy and distribute verbatim copies of this
  license document, but changing it is not allowed.

# ** 0. PREAMBLE
** 0. PREAMBLE

#    The purpose of this License is to make a manual, textbook, or other
#    functional and useful document "free" in the sense of freedom: to assure
#    everyone the effective freedom to copy and redistribute it, with or
#    without modifying it, either commercially or noncommercially.
#    Secondarily, this License preserves for the author and publisher a way to
#    get credit for their work, while not being considered responsible for
#    modifications made by others.
   The purpose of this License is to make a manual, textbook, or other
   functional and useful document "free" in the sense of freedom: to assure
   everyone the effective freedom to copy and redistribute it, with or
   without modifying it, either commercially or noncommercially.
   Secondarily, this License preserves for the author and publisher a way to
   get credit for their work, while not being considered responsible for
   modifications made by others.

#    This License is a kind of "copyleft", which means that derivative works of
#    the document must themselves be free in the same sense. It complements
#    the GNU General Public License, which is a copyleft license designed for
#    free software.
   This License is a kind of "copyleft", which means that derivative works of
   the document must themselves be free in the same sense. It complements
   the GNU General Public License, which is a copyleft license designed for
   free software.

#    We have designed this License in order to use it for manuals for free
#    software, because free software needs free documentation: a free program
#    should come with manuals providing the same freedoms that the software
#    does. But this License is not limited to software manuals; it can be used
#    for any textual work, regardless of subject matter or whether it is
#    published as a printed book. We recommend this License principally for
#    works whose purpose is instruction or reference.
   We have designed this License in order to use it for manuals for free
   software, because free software needs free documentation: a free program
   should come with manuals providing the same freedoms that the software
   does. But this License is not limited to software manuals; it can be used
   for any textual work, regardless of subject matter or whether it is
   published as a printed book. We recommend this License principally for
   works whose purpose is instruction or reference.

# ** 1. APPLICABILITY AND DEFINITIONS
** 1. APPLICABILITY AND DEFINITIONS

#    This License applies to any manual or other work, in any medium, that
#    contains a notice placed by the copyright holder saying it can be
#    distributed under the terms of this License. Such a notice grants a
#    world-wide, royalty-free license, unlimited in duration, to use that work
#    under the conditions stated herein. The "Document", below, refers to any
#    such manual or work. Any member of the public is a licensee, and is
#    addressed as "you". You accept the license if you copy, modify or
#    distribute the work in a way requiring permission under copyright law.
   This License applies to any manual or other work, in any medium, that
   contains a notice placed by the copyright holder saying it can be
   distributed under the terms of this License. Such a notice grants a
   world-wide, royalty-free license, unlimited in duration, to use that work
   under the conditions stated herein. The "Document", below, refers to any
   such manual or work. Any member of the public is a licensee, and is
   addressed as "you". You accept the license if you copy, modify or
   distribute the work in a way requiring permission under copyright law.

#    A "Modified Version" of the Document means any work containing the
#    Document or a portion of it, either copied verbatim, or with modifications
#    and/or translated into another language.
   A "Modified Version" of the Document means any work containing the
   Document or a portion of it, either copied verbatim, or with modifications
   and/or translated into another language.

#    A "Secondary Section" is a named appendix or a front-matter section of the
#    Document that deals exclusively with the relationship of the publishers or
#    authors of the Document to the Document's overall subject (or to related
#    matters) and contains nothing that could fall directly within that overall
#    subject.  (Thus, if the Document is in part a textbook of mathematics, a
#    Secondary Section may not explain any mathematics.)  The relationship
#    could be a matter of historical connection with the subject or with
#    related matters, or of legal, commercial, philosophical, ethical or
#    political position regarding them.
   A "Secondary Section" is a named appendix or a front-matter section of the
   Document that deals exclusively with the relationship of the publishers or
   authors of the Document to the Document's overall subject (or to related
   matters) and contains nothing that could fall directly within that overall
   subject.  (Thus, if the Document is in part a textbook of mathematics, a
   Secondary Section may not explain any mathematics.)  The relationship
   could be a matter of historical connection with the subject or with
   related matters, or of legal, commercial, philosophical, ethical or
   political position regarding them.

#    The "Invariant Sections" are certain Secondary Sections whose titles are
#    designated, as being those of Invariant Sections, in the notice that says
#    that the Document is released under this License. If a section does not
#    fit the above definition of Secondary then it is not allowed to be
#    designated as Invariant. The Document may contain zero Invariant
#    Sections. If the Document does not identify any Invariant Sections then
#    there are none.
   The "Invariant Sections" are certain Secondary Sections whose titles are
   designated, as being those of Invariant Sections, in the notice that says
   that the Document is released under this License. If a section does not
   fit the above definition of Secondary then it is not allowed to be
   designated as Invariant. The Document may contain zero Invariant
   Sections. If the Document does not identify any Invariant Sections then
   there are none.

#    The "Cover Texts" are certain short passages of text that are listed, as
#    Front-Cover Texts or Back-Cover Texts, in the notice that says that the
#    Document is released under this License. A Front-Cover Text may be at
#    most 5 words, and a Back-Cover Text may be at most 25 words.
   The "Cover Texts" are certain short passages of text that are listed, as
   Front-Cover Texts or Back-Cover Texts, in the notice that says that the
   Document is released under this License. A Front-Cover Text may be at
   most 5 words, and a Back-Cover Text may be at most 25 words.

#    A "Transparent" copy of the Document means a machine-readable copy,
#    represented in a format whose specification is available to the general
#    public, that is suitable for revising the document straightforwardly with
#    generic text editors or (for images composed of pixels) generic paint
#    programs or (for drawings) some widely available drawing editor, and that
#    is suitable for input to text formatters or for automatic translation to a
#    variety of formats suitable for input to text formatters. A copy made in
#    an otherwise Transparent file format whose markup, or absence of markup,
#    has been arranged to thwart or discourage subsequent modification by
#    readers is not Transparent. An image format is not Transparent if used
#    for any substantial amount of text. A copy that is not "Transparent" is
#    called "Opaque".
   A "Transparent" copy of the Document means a machine-readable copy,
   represented in a format whose specification is available to the general
   public, that is suitable for revising the document straightforwardly with
   generic text editors or (for images composed of pixels) generic paint
   programs or (for drawings) some widely available drawing editor, and that
   is suitable for input to text formatters or for automatic translation to a
   variety of formats suitable for input to text formatters. A copy made in
   an otherwise Transparent file format whose markup, or absence of markup,
   has been arranged to thwart or discourage subsequent modification by
   readers is not Transparent. An image format is not Transparent if used
   for any substantial amount of text. A copy that is not "Transparent" is
   called "Opaque".

#    Examples of suitable formats for Transparent copies include plain ASCII
#    without markup, Texinfo input format, LaTeX input format, SGML or XML
#    using a publicly available DTD, and standard-conforming simple HTML,
#    PostScript or PDF designed for human modification. Examples of
#    transparent image formats include PNG, XCF and JPG. Opaque formats
#    include proprietary formats that can be read and edited only by
#    proprietary word processors, SGML or XML for which the DTD and/or
#    processing tools are not generally available, and the machine-generated
#    HTML, PostScript or PDF produced by some word processors for output
#    purposes only.
   Examples of suitable formats for Transparent copies include plain ASCII
   without markup, Texinfo input format, LaTeX input format, SGML or XML
   using a publicly available DTD, and standard-conforming simple HTML,
   PostScript or PDF designed for human modification. Examples of
   transparent image formats include PNG, XCF and JPG. Opaque formats
   include proprietary formats that can be read and edited only by
   proprietary word processors, SGML or XML for which the DTD and/or
   processing tools are not generally available, and the machine-generated
   HTML, PostScript or PDF produced by some word processors for output
   purposes only.

#    The "Title Page" means, for a printed book, the title page itself, plus
#    such following pages as are needed to hold, legibly, the material this
#    License requires to appear in the title page. For works in formats which
#    do not have any title page as such, "Title Page" means the text near the
#    most prominent appearance of the work's title, preceding the beginning of
#    the body of the text.
   The "Title Page" means, for a printed book, the title page itself, plus
   such following pages as are needed to hold, legibly, the material this
   License requires to appear in the title page. For works in formats which
   do not have any title page as such, "Title Page" means the text near the
   most prominent appearance of the work's title, preceding the beginning of
   the body of the text.

#    The "publisher" means any person or entity that distributes copies of the
#    Document to the public.
   The "publisher" means any person or entity that distributes copies of the
   Document to the public.

#    A section "Entitled XYZ" means a named subunit of the Document whose title
#    either is precisely XYZ or contains XYZ in parentheses following text that
#    translates XYZ in another language.  (Here XYZ stands for a specific
#    section name mentioned below, such as "Acknowledgements", "Dedications",
#    "Endorsements", or "History".)  To "Preserve the Title" of such a section
#    when you modify the Document means that it remains a section "Entitled
#    XYZ" according to this definition.
   A section "Entitled XYZ" means a named subunit of the Document whose title
   either is precisely XYZ or contains XYZ in parentheses following text that
   translates XYZ in another language.  (Here XYZ stands for a specific
   section name mentioned below, such as "Acknowledgements", "Dedications",
   "Endorsements", or "History".)  To "Preserve the Title" of such a section
   when you modify the Document means that it remains a section "Entitled
   XYZ" according to this definition.

#    The Document may include Warranty Disclaimers next to the notice which
#    states that this License applies to the Document. These Warranty
#    Disclaimers are considered to be included by reference in this License,
#    but only as regards disclaiming warranties: any other implication that
#    these Warranty Disclaimers may have is void and has no effect on the
#    meaning of this License.
   The Document may include Warranty Disclaimers next to the notice which
   states that this License applies to the Document. These Warranty
   Disclaimers are considered to be included by reference in this License,
   but only as regards disclaiming warranties: any other implication that
   these Warranty Disclaimers may have is void and has no effect on the
   meaning of this License.

# ** 2. VERBATIM COPYING
** 2. VERBATIM COPYING

#    You may copy and distribute the Document in any medium, either
#    commercially or noncommercially, provided that this License, the copyright
#    notices, and the license notice saying this License applies to the
#    Document are reproduced in all copies, and that you add no other
#    conditions whatsoever to those of this License. You may not use technical
#    measures to obstruct or control the reading or further copying of the
#    copies you make or distribute. However, you may accept compensation in
#    exchange for copies. If you distribute a large enough number of copies
#    you must also follow the conditions in section 3.
   You may copy and distribute the Document in any medium, either
   commercially or noncommercially, provided that this License, the copyright
   notices, and the license notice saying this License applies to the
   Document are reproduced in all copies, and that you add no other
   conditions whatsoever to those of this License. You may not use technical
   measures to obstruct or control the reading or further copying of the
   copies you make or distribute. However, you may accept compensation in
   exchange for copies. If you distribute a large enough number of copies
   you must also follow the conditions in section 3.

#    You may also lend copies, under the same conditions stated above, and you
#    may publicly display copies.
   You may also lend copies, under the same conditions stated above, and you
   may publicly display copies.

# ** 3. COPYING IN QUANTITY
** 3. COPYING IN QUANTITY

#    If you publish printed copies (or copies in media that commonly have
#    printed covers) of the Document, numbering more than 100, and the
#    Document's license notice requires Cover Texts, you must enclose the
#    copies in covers that carry, clearly and legibly, all these Cover Texts:
#    Front-Cover Texts on the front cover, and Back-Cover Texts on the back
#    cover. Both covers must also clearly and legibly identify you as the
#    publisher of these copies. The front cover must present the full title
#    with all words of the title equally prominent and visible. You may add
#    other material on the covers in addition. Copying with changes limited to
#    the covers, as long as they preserve the title of the Document and satisfy
#    these conditions, can be treated as verbatim copying in other respects.
   If you publish printed copies (or copies in media that commonly have
   printed covers) of the Document, numbering more than 100, and the
   Document's license notice requires Cover Texts, you must enclose the
   copies in covers that carry, clearly and legibly, all these Cover Texts:
   Front-Cover Texts on the front cover, and Back-Cover Texts on the back
   cover. Both covers must also clearly and legibly identify you as the
   publisher of these copies. The front cover must present the full title
   with all words of the title equally prominent and visible. You may add
   other material on the covers in addition. Copying with changes limited to
   the covers, as long as they preserve the title of the Document and satisfy
   these conditions, can be treated as verbatim copying in other respects.

#    If the required texts for either cover are too voluminous to fit legibly,
#    you should put the first ones listed (as many as fit reasonably) on the
#    actual cover, and continue the rest onto adjacent pages.
   If the required texts for either cover are too voluminous to fit legibly,
   you should put the first ones listed (as many as fit reasonably) on the
   actual cover, and continue the rest onto adjacent pages.

#    If you publish or distribute Opaque copies of the Document numbering more
#    than 100, you must either include a machine-readable Transparent copy
#    along with each Opaque copy, or state in or with each Opaque copy a
#    computer-network location from which the general network-using public has
#    access to download using public-standard network protocols a complete
#    Transparent copy of the Document, free of added material. If you use the
#    latter option, you must take reasonably prudent steps, when you begin
#    distribution of Opaque copies in quantity, to ensure that this Transparent
#    copy will remain thus accessible at the stated location until at least one
#    year after the last time you distribute an Opaque copy (directly or
#    through your agents or retailers) of that edition to the public.
   If you publish or distribute Opaque copies of the Document numbering more
   than 100, you must either include a machine-readable Transparent copy
   along with each Opaque copy, or state in or with each Opaque copy a
   computer-network location from which the general network-using public has
   access to download using public-standard network protocols a complete
   Transparent copy of the Document, free of added material. If you use the
   latter option, you must take reasonably prudent steps, when you begin
   distribution of Opaque copies in quantity, to ensure that this Transparent
   copy will remain thus accessible at the stated location until at least one
   year after the last time you distribute an Opaque copy (directly or
   through your agents or retailers) of that edition to the public.

#    It is requested, but not required, that you contact the authors of the
#    Document well before redistributing any large number of copies, to give
#    them a chance to provide you with an updated version of the Document.
   It is requested, but not required, that you contact the authors of the
   Document well before redistributing any large number of copies, to give
   them a chance to provide you with an updated version of the Document.

# ** 4. MODIFICATIONS
** 4. MODIFICATIONS

#    You may copy and distribute a Modified Version of the Document under the
#    conditions of sections 2 and 3 above, provided that you release the
#    Modified Version under precisely this License, with the Modified Version
#    filling the role of the Document, thus licensing distribution and
#    modification of the Modified Version to whoever possesses a copy of it.
#    In addition, you must do these things in the Modified Version:
   You may copy and distribute a Modified Version of the Document under the
   conditions of sections 2 and 3 above, provided that you release the
   Modified Version under precisely this License, with the Modified Version
   filling the role of the Document, thus licensing distribution and
   modification of the Modified Version to whoever possesses a copy of it.
   In addition, you must do these things in the Modified Version:

#    A. Use in the Title Page (and on the covers, if any) a title distinct from
#       that of the Document, and from those of previous versions (which
#       should, if there were any, be listed in the History section of the
#       Document). You may use the same title as a previous version if the
#       original publisher of that version gives permission.
   A. Use in the Title Page (and on the covers, if any) a title distinct from
      that of the Document, and from those of previous versions (which
      should, if there were any, be listed in the History section of the
      Document). You may use the same title as a previous version if the
      original publisher of that version gives permission.

#    B. List on the Title Page, as authors, one or more persons or entities
#       responsible for authorship of the modifications in the Modified
#       Version, together with at least five of the principal authors of the
#       Document (all of its principal authors, if it has fewer than five),
#       unless they release you from this requirement.
   B. List on the Title Page, as authors, one or more persons or entities
      responsible for authorship of the modifications in the Modified
      Version, together with at least five of the principal authors of the
      Document (all of its principal authors, if it has fewer than five),
      unless they release you from this requirement.

#    C. State on the Title page the name of the publisher of the Modified
#       Version, as the publisher.
   C. State on the Title page the name of the publisher of the Modified
      Version, as the publisher.

#    D. Preserve all the copyright notices of the Document.
   D. Preserve all the copyright notices of the Document.

#    E. Add an appropriate copyright notice for your modifications adjacent to
#       the other copyright notices.
   E. Add an appropriate copyright notice for your modifications adjacent to
      the other copyright notices.

#    F. Include, immediately after the copyright notices, a license notice
#       giving the public permission to use the Modified Version under the
#       terms of this License, in the form shown in the Addendum below.
   F. Include, immediately after the copyright notices, a license notice
      giving the public permission to use the Modified Version under the
      terms of this License, in the form shown in the Addendum below.

#    G. Preserve in that license notice the full lists of Invariant Sections
#       and required Cover Texts given in the Document's license notice.
   G. Preserve in that license notice the full lists of Invariant Sections
      and required Cover Texts given in the Document's license notice.

#    H. Include an unaltered copy of this License.
   H. Include an unaltered copy of this License.

#    I. Preserve the section Entitled "History", Preserve its Title, and add to
#       it an item stating at least the title, year, new authors, and publisher
#       of the Modified Version as given on the Title Page. If there is no
#       section Entitled "History" in the Document, create one stating the
#       title, year, authors, and publisher of the Document as given on its
#       Title Page, then add an item describing the Modified Version as stated
#       in the previous sentence.
   I. Preserve the section Entitled "History", Preserve its Title, and add to
      it an item stating at least the title, year, new authors, and publisher
      of the Modified Version as given on the Title Page. If there is no
      section Entitled "History" in the Document, create one stating the
      title, year, authors, and publisher of the Document as given on its
      Title Page, then add an item describing the Modified Version as stated
      in the previous sentence.

#    J. Preserve the network location, if any, given in the Document for public
#       access to a Transparent copy of the Document, and likewise the network
#       locations given in the Document for previous versions it was based on.
#       These may be placed in the "History" section. You may omit a network
#       location for a work that was published at least four years before the
#       Document itself, or if the original publisher of the version it refers
#       to gives permission.
   J. Preserve the network location, if any, given in the Document for public
      access to a Transparent copy of the Document, and likewise the network
      locations given in the Document for previous versions it was based on.
      These may be placed in the "History" section. You may omit a network
      location for a work that was published at least four years before the
      Document itself, or if the original publisher of the version it refers
      to gives permission.

#    K. For any section Entitled "Acknowledgements" or "Dedications", Preserve
#       the Title of the section, and preserve in the section all the substance
#       and tone of each of the contributor acknowledgements and/or dedications
#       given therein.
   K. For any section Entitled "Acknowledgements" or "Dedications", Preserve
      the Title of the section, and preserve in the section all the substance
      and tone of each of the contributor acknowledgements and/or dedications
      given therein.

#    L. Preserve all the Invariant Sections of the Document, unaltered in their
#       text and in their titles. Section numbers or the equivalent are not
#       considered part of the section titles.
   L. Preserve all the Invariant Sections of the Document, unaltered in their
      text and in their titles. Section numbers or the equivalent are not
      considered part of the section titles.

#    M. Delete any section Entitled "Endorsements". Such a section may not be
#       included in the Modified Version.
   M. Delete any section Entitled "Endorsements". Such a section may not be
      included in the Modified Version.

#    N. Do not retitle any existing section to be Entitled "Endorsements" or to
#       conflict in title with any Invariant Section.
   N. Do not retitle any existing section to be Entitled "Endorsements" or to
      conflict in title with any Invariant Section.

#    O. Preserve any Warranty Disclaimers.
   O. Preserve any Warranty Disclaimers.


#    If the Modified Version includes new front-matter sections or appendices
#    that qualify as Secondary Sections and contain no material copied from the
#    Document, you may at your option designate some or all of these sections
#    as invariant. To do this, add their titles to the list of Invariant
#    Sections in the Modified Version's license notice. These titles must be
#    distinct from any other section titles.
   If the Modified Version includes new front-matter sections or appendices
   that qualify as Secondary Sections and contain no material copied from the
   Document, you may at your option designate some or all of these sections
   as invariant. To do this, add their titles to the list of Invariant
   Sections in the Modified Version's license notice. These titles must be
   distinct from any other section titles.

#    You may add a section Entitled "Endorsements", provided it contains
#    nothing but endorsements of your Modified Version by various parties--for
#    example, statements of peer review or that the text has been approved by
#    an organization as the authoritative definition of a standard.
   You may add a section Entitled "Endorsements", provided it contains
   nothing but endorsements of your Modified Version by various parties--for
   example, statements of peer review or that the text has been approved by
   an organization as the authoritative definition of a standard.

#    You may add a passage of up to five words as a Front-Cover Text, and a
#    passage of up to 25 words as a Back-Cover Text, to the end of the list of
#    Cover Texts in the Modified Version. Only one passage of Front-Cover Text
#    and one of Back-Cover Text may be added by (or through arrangements made
#    by) any one entity. If the Document already includes a cover text for the
#    same cover, previously added by you or by arrangement made by the same
#    entity you are acting on behalf of, you may not add another; but you may
#    replace the old one, on explicit permission from the previous publisher
#    that added the old one.
   You may add a passage of up to five words as a Front-Cover Text, and a
   passage of up to 25 words as a Back-Cover Text, to the end of the list of
   Cover Texts in the Modified Version. Only one passage of Front-Cover Text
   and one of Back-Cover Text may be added by (or through arrangements made
   by) any one entity. If the Document already includes a cover text for the
   same cover, previously added by you or by arrangement made by the same
   entity you are acting on behalf of, you may not add another; but you may
   replace the old one, on explicit permission from the previous publisher
   that added the old one.

#    The author(s) and publisher(s) of the Document do not by this License give
#    permission to use their names for publicity for or to assert or imply
#    endorsement of any Modified Version.
   The author(s) and publisher(s) of the Document do not by this License give
   permission to use their names for publicity for or to assert or imply
   endorsement of any Modified Version.

# ** 5. COMBINING DOCUMENTS
** 5. COMBINING DOCUMENTS

#    You may combine the Document with other documents released under this
#    License, under the terms defined in section 4 above for modified versions,
#    provided that you include in the combination all of the Invariant Sections
#    of all of the original documents, unmodified, and list them all as
#    Invariant Sections of your combined work in its license notice, and that
#    you preserve all their Warranty Disclaimers.
   You may combine the Document with other documents released under this
   License, under the terms defined in section 4 above for modified versions,
   provided that you include in the combination all of the Invariant Sections
   of all of the original documents, unmodified, and list them all as
   Invariant Sections of your combined work in its license notice, and that
   you preserve all their Warranty Disclaimers.

#    The combined work need only contain one copy of this License, and multiple
#    identical Invariant Sections may be replaced with a single copy. If there
#    are multiple Invariant Sections with the same name but different contents,
#    make the title of each such section unique by adding at the end of it, in
#    parentheses, the name of the original author or publisher of that section
#    if known, or else a unique number. Make the same adjustment to the
#    section titles in the list of Invariant Sections in the license notice of
#    the combined work.
   The combined work need only contain one copy of this License, and multiple
   identical Invariant Sections may be replaced with a single copy. If there
   are multiple Invariant Sections with the same name but different contents,
   make the title of each such section unique by adding at the end of it, in
   parentheses, the name of the original author or publisher of that section
   if known, or else a unique number. Make the same adjustment to the
   section titles in the list of Invariant Sections in the license notice of
   the combined work.

#    In the combination, you must combine any sections Entitled "History" in
#    the various original documents, forming one section Entitled "History";
#    likewise combine any sections Entitled "Acknowledgements", and any
#    sections Entitled "Dedications". You must delete all sections Entitled
#    "Endorsements".
   In the combination, you must combine any sections Entitled "History" in
   the various original documents, forming one section Entitled "History";
   likewise combine any sections Entitled "Acknowledgements", and any
   sections Entitled "Dedications". You must delete all sections Entitled
   "Endorsements".

# ** 6. COLLECTIONS OF DOCUMENTS
** 6. COLLECTIONS OF DOCUMENTS

#    You may make a collection consisting of the Document and other documents
#    released under this License, and replace the individual copies of this
#    License in the various documents with a single copy that is included in
#    the collection, provided that you follow the rules of this License for
#    verbatim copying of each of the documents in all other respects.
   You may make a collection consisting of the Document and other documents
   released under this License, and replace the individual copies of this
   License in the various documents with a single copy that is included in
   the collection, provided that you follow the rules of this License for
   verbatim copying of each of the documents in all other respects.

#    You may extract a single document from such a collection, and distribute
#    it individually under this License, provided you insert a copy of this
#    License into the extracted document, and follow this License in all other
#    respects regarding verbatim copying of that document.
   You may extract a single document from such a collection, and distribute
   it individually under this License, provided you insert a copy of this
   License into the extracted document, and follow this License in all other
   respects regarding verbatim copying of that document.

# ** 7. AGGREGATION WITH INDEPENDENT WORKS
** 7. AGGREGATION WITH INDEPENDENT WORKS

#    A compilation of the Document or its derivatives with other separate and
#    independent documents or works, in or on a volume of a storage or
#    distribution medium, is called an "aggregate" if the copyright resulting
#    from the compilation is not used to limit the legal rights of the
#    compilation's users beyond what the individual works permit. When the
#    Document is included in an aggregate, this License does not apply to the
#    other works in the aggregate which are not themselves derivative works of
#    the Document.
   A compilation of the Document or its derivatives with other separate and
   independent documents or works, in or on a volume of a storage or
   distribution medium, is called an "aggregate" if the copyright resulting
   from the compilation is not used to limit the legal rights of the
   compilation's users beyond what the individual works permit. When the
   Document is included in an aggregate, this License does not apply to the
   other works in the aggregate which are not themselves derivative works of
   the Document.

#    If the Cover Text requirement of section 3 is applicable to these copies
#    of the Document, then if the Document is less than one half of the entire
#    aggregate, the Document's Cover Texts may be placed on covers that bracket
#    the Document within the aggregate, or the electronic equivalent of covers
#    if the Document is in electronic form. Otherwise they must appear on
#    printed covers that bracket the whole aggregate.
   If the Cover Text requirement of section 3 is applicable to these copies
   of the Document, then if the Document is less than one half of the entire
   aggregate, the Document's Cover Texts may be placed on covers that bracket
   the Document within the aggregate, or the electronic equivalent of covers
   if the Document is in electronic form. Otherwise they must appear on
   printed covers that bracket the whole aggregate.

# ** 8. TRANSLATION
** 8. TRANSLATION

#    Translation is considered a kind of modification, so you may distribute
#    translations of the Document under the terms of section 4. Replacing
#    Invariant Sections with translations requires special permission from
#    their copyright holders, but you may include translations of some or all
#    Invariant Sections in addition to the original versions of these Invariant
#    Sections. You may include a translation of this License, and all the
#    license notices in the Document, and any Warranty Disclaimers, provided
#    that you also include the original English version of this License and the
#    original versions of those notices and disclaimers. In case of a
#    disagreement between the translation and the original version of this
#    License or a notice or disclaimer, the original version will prevail.
   Translation is considered a kind of modification, so you may distribute
   translations of the Document under the terms of section 4. Replacing
   Invariant Sections with translations requires special permission from
   their copyright holders, but you may include translations of some or all
   Invariant Sections in addition to the original versions of these Invariant
   Sections. You may include a translation of this License, and all the
   license notices in the Document, and any Warranty Disclaimers, provided
   that you also include the original English version of this License and the
   original versions of those notices and disclaimers. In case of a
   disagreement between the translation and the original version of this
   License or a notice or disclaimer, the original version will prevail.

#    If a section in the Document is Entitled "Acknowledgements",
#    "Dedications", or "History", the requirement (section 4) to Preserve its
#    Title (section 1) will typically require changing the actual title.
   If a section in the Document is Entitled "Acknowledgements",
   "Dedications", or "History", the requirement (section 4) to Preserve its
   Title (section 1) will typically require changing the actual title.

# ** 9. TERMINATION
** 9. TERMINATION

#    You may not copy, modify, sublicense, or distribute the Document except as
#    expressly provided under this License. Any attempt otherwise to copy,
#    modify, sublicense, or distribute it is void, and will automatically
#    terminate your rights under this License.
   You may not copy, modify, sublicense, or distribute the Document except as
   expressly provided under this License. Any attempt otherwise to copy,
   modify, sublicense, or distribute it is void, and will automatically
   terminate your rights under this License.

#    However, if you cease all violation of this License, then your license
#    from a particular copyright holder is reinstated (a) provisionally, unless
#    and until the copyright holder explicitly and finally terminates your
#    license, and (b) permanently, if the copyright holder fails to notify you
#    of the violation by some reasonable means prior to 60 days after the
#    cessation.
   However, if you cease all violation of this License, then your license
   from a particular copyright holder is reinstated (a) provisionally, unless
   and until the copyright holder explicitly and finally terminates your
   license, and (b) permanently, if the copyright holder fails to notify you
   of the violation by some reasonable means prior to 60 days after the
   cessation.

#    Moreover, your license from a particular copyright holder is reinstated
#    permanently if the copyright holder notifies you of the violation by some
#    reasonable means, this is the first time you have received notice of
#    violation of this License (for any work) from that copyright holder, and
#    you cure the violation prior to 30 days after your receipt of the notice.
   Moreover, your license from a particular copyright holder is reinstated
   permanently if the copyright holder notifies you of the violation by some
   reasonable means, this is the first time you have received notice of
   violation of this License (for any work) from that copyright holder, and
   you cure the violation prior to 30 days after your receipt of the notice.

#    Termination of your rights under this section does not terminate the
#    licenses of parties who have received copies or rights from you under this
#    License. If your rights have been terminated and not permanently
#    reinstated, receipt of a copy of some or all of the same material does not
#    give you any rights to use it.
   Termination of your rights under this section does not terminate the
   licenses of parties who have received copies or rights from you under this
   License. If your rights have been terminated and not permanently
   reinstated, receipt of a copy of some or all of the same material does not
   give you any rights to use it.

# ** 10. FUTURE REVISIONS OF THIS LICENSE
** 10. FUTURE REVISIONS OF THIS LICENSE

#    The Free Software Foundation may publish new, revised versions of the GNU
#    Free Documentation License from time to time. Such new versions will be
#    similar in spirit to the present version, but may differ in detail to
#    address new problems or concerns. See @l(http://www.gnu.org/copyleft/).
   The Free Software Foundation may publish new, revised versions of the GNU
   Free Documentation License from time to time. Such new versions will be
   similar in spirit to the present version, but may differ in detail to
   address new problems or concerns. See @l(http://www.gnu.org/copyleft/).

#    Each version of the License is given a distinguishing version number. If
#    the Document specifies that a particular numbered version of this License
#    "or any later version" applies to it, you have the option of following the
#    terms and conditions either of that specified version or of any later
#    version that has been published (not as a draft) by the Free Software
#    Foundation. If the Document does not specify a version number of this
#    License, you may choose any version ever published (not as a draft) by the
#    Free Software Foundation. If the Document specifies that a proxy can
#    decide which future versions of this License can be used, that proxy's
#    public statement of acceptance of a version permanently authorizes you to
#    choose that version for the Document.
   Each version of the License is given a distinguishing version number. If
   the Document specifies that a particular numbered version of this License
   "or any later version" applies to it, you have the option of following the
   terms and conditions either of that specified version or of any later
   version that has been published (not as a draft) by the Free Software
   Foundation. If the Document does not specify a version number of this
   License, you may choose any version ever published (not as a draft) by the
   Free Software Foundation. If the Document specifies that a proxy can
   decide which future versions of this License can be used, that proxy's
   public statement of acceptance of a version permanently authorizes you to
   choose that version for the Document.

# ** 11. RELICENSING
** 11. RELICENSING

#    "Massive Multiauthor Collaboration Site" (or "MMC Site") means any World
#    Wide Web server that publishes copyrightable works and also provides
#    prominent facilities for anybody to edit those works. A public wiki that
#    anybody can edit is an example of such a server. A "Massive Multiauthor
#    Collaboration" (or "MMC") contained in the site means any set of
#    copyrightable works thus published on the MMC site.
   "Massive Multiauthor Collaboration Site" (or "MMC Site") means any World
   Wide Web server that publishes copyrightable works and also provides
   prominent facilities for anybody to edit those works. A public wiki that
   anybody can edit is an example of such a server. A "Massive Multiauthor
   Collaboration" (or "MMC") contained in the site means any set of
   copyrightable works thus published on the MMC site.

#    "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 license
#    published by Creative Commons Corporation, a not-for-profit corporation
#    with a principal place of business in San Francisco, California, as well
#    as future copyleft versions of that license published by that same
#    organization.
   "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 license
   published by Creative Commons Corporation, a not-for-profit corporation
   with a principal place of business in San Francisco, California, as well
   as future copyleft versions of that license published by that same
   organization.

#    "Incorporate" means to publish or republish a Document, in whole or in
#    part, as part of another Document.
   "Incorporate" means to publish or republish a Document, in whole or in
   part, as part of another Document.

#    An MMC is "eligible for relicensing" if it is licensed under this License,
#    and if all works that were first published under this License somewhere
#    other than this MMC, and subsequently incorporated in whole or in part
#    into the MMC, (1) had no cover texts or invariant sections, and (2) were
#    thus incorporated prior to November 1, 2008.
   An MMC is "eligible for relicensing" if it is licensed under this License,
   and if all works that were first published under this License somewhere
   other than this MMC, and subsequently incorporated in whole or in part
   into the MMC, (1) had no cover texts or invariant sections, and (2) were
   thus incorporated prior to November 1, 2008.

#    The operator of an MMC Site may republish an MMC contained in the site
#    under CC-BY-SA on the same site at any time before August 1, 2009,
#    provided the MMC is eligible for relicensing.
   The operator of an MMC Site may republish an MMC contained in the site
   under CC-BY-SA on the same site at any time before August 1, 2009,
   provided the MMC is eligible for relicensing.

# * ADDENDUM: How to use this License for your documents
* ADDENDUM: How to use this License for your documents

#   To use this License in a document you have written, include a copy of the
#   License in the document and put the following copyright and license notices
#   just after the title page:
  To use this License in a document you have written, include a copy of the
  License in the document and put the following copyright and license notices
  just after the title page:

#   ..pre >
#     Copyright (c)  YEAR  YOUR NAME.
#     Permission is granted to copy, distribute and/or modify this document
#     under the terms of the GNU Free Documentation License, Version 1.3
#     or any later version published by the Free Software Foundation;
#     with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
#     A copy of the license is included in the section entitled "GNU
#     Free Documentation License".
#   < pre..
  ..pre >
    Copyright (c)  YEAR  YOUR NAME.
    Permission is granted to copy, distribute and/or modify this document
    under the terms of the GNU Free Documentation License, Version 1.3
    or any later version published by the Free Software Foundation;
    with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
    A copy of the license is included in the section entitled "GNU
    Free Documentation License".
  < pre..

#   If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
#   replace the "with...Texts." line with this:
  If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
  replace the "with...Texts." line with this:

#   ..pre >
#     with the Invariant Sections being LIST THEIR TITLES, with the
#     Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
#   < pre..
  ..pre >
    with the Invariant Sections being LIST THEIR TITLES, with the
    Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
  < pre..

#   If you have Invariant Sections without Cover Texts, or some other
#   combination of the three, merge those two alternatives to suit the
#   situation.
  If you have Invariant Sections without Cover Texts, or some other
  combination of the three, merge those two alternatives to suit the
  situation.

#   If your document contains nontrivial examples of program code, we recommend
#   releasing these examples in parallel under your choice of free software
#   license, such as the GNU General Public License, to permit their use in
#   free software.
  If your document contains nontrivial examples of program code, we recommend
  releasing these examples in parallel under your choice of free software
  license, such as the GNU General Public License, to permit their use in
  free software.

# * About the Author
** Acerca del Autor

#   Robert J. Chassell has worked with GNU Emacs since 1985. He writes and
#   edits, teaches Emacs and Emacs Lisp, and speaks throughout the world on
#   software freedom. Chassell was a founding Director and Treasurer of the
#   Free Software Foundation, Inc. He is co-author of the @q{Texinfo} manual,
#   and has edited more than a dozen other books. He graduated from Cambridge
#   University, in England. He has an abiding interest in social and economic
#   history and flies his own airplane.
   Robert J. Chassell ha trabajado con GNU Emacs desde 1985. Él escribe, edita y
   enseña Emacs y Emacs Lisp, y habla en todo el mundo sobre la libertad del
   software. Chassell fue Director fundador y Tesorero de la Free Software
   Foundation, Inc. Es coautor del manual @q(Texinfo) y ha editado mas de una
   docena de libros.  Se graduó en la Universidad de Cambridge, en Inglaterra.
   Tiene un interés permanente en historia económica y social y vuela su propio
   aeroplano

# * footnotes
* footnotes

#  :: @N{1} :: The single apostrophe or quotation mark is an abbreviation for
#     the function @c{quote}; you need not think about functions now; functions
#     are defined in Section @l{#Generate an Error Message}.
 :: @N{1} :: El apóstrofo o comilla es una abreviación para la función
    @c{quote}; no es necesario pensar en las funciones ahora; las funciones
    se definen en la Seccion @l{#Generar un mensaje de error}.

#  :: @N{2} :: It is curious to track the path by which the word ‘argument’
#     came to have two different meanings, one in mathematics and the other in
#     everyday English. According to the @q{Oxford English Dictionary}, the
#     word derives from the Latin for @'{to make clear, prove}; thus it came to
#     mean, by one thread of derivation, ‘the evidence offered as proof’, which
#     is to say, ‘the information offered’, which led to its meaning in Lisp.
#     But in the other thread of derivation, it came to mean ‘to assert in a
#     manner against which others may make counter assertions’, which led to
#     the meaning of the word as a disputation.  (Note here that the English
#     word has two different definitions attached to it at the same time. By
#     contrast, in Emacs Lisp, a symbol cannot have two different function
#     definitions at the same time.)
 :: @N{2} :: Es curioso seguir el camino por el que la palabra ‘argumento’ llego
    a tener dos significados distintos, uno en matemáticas y otro en el inglés
    cotidiano. De acuerdo al @e{Oxford English Dictionary}, la palabra deriva
    del Latín para @'{dejar claro, probar}; asi llego a significar, por un hilo
    de derivación, ‘la evidencia ofrecida como prueba’, es decir ‘la informacion
    que se ofrece’, lo que conduce a su significado en Lisp. Pero en el otro hilo
    de la derivación, paso a significar ‘afirmar de una manera contra la cual
    otros pueden hacer afirmaciones contrarias’, lo que llevó al significado de
    la palabra como disputa. (Notese aqui que la palabra Inglésa tiene dos
    definiciones distintas al mismo tiempo. En contraste, en Emacs Lisp, un
    símbolo no puede tener dos definiciones de funcion diferentes al mismo
    tiempo.)

#  :: @N{3} :: @c{(quote hello)} is an expansion of the abbreviation
#     @c{'hello}.
 :: @N{3} :: @c{(quote hola)} es una expansión de la abreviatura @c{'hola}.

#  :: @N{4} :: Actually, you can use @c{%s} to print a number. It is
#     non-specific.  @c{%d} prints only the part of a number left of a decimal
#     point, and not anything that is not a number.
 :: @N{4} :: En realidad, se puede utilizar @c{%s} para imprimir un número. No
    es específico. @c{%d} solo imprime la parte de un número a la izquierda
    del punto decimal, excluyendo cualquier cosa que no sea un número.

#  :: @N{5} :: Actually, by default, if the buffer from which you just switched
#     is visible to you in another window, @c{other-buffer} will choose the
#     most recent buffer that you cannot see; this is a subtlety that I often
#     forget.
 :: @N{5} :: De hecho, por defecto, si el búfer desde el que acabas de
    cambiar es visible por tí en otra ventana, @c{other-buffer} elegirá el
    búfer más reciente que no puedas ver; esta es una sutileza que a menudo
    olvido.

#  :: @N{6} :: Or rather, to save typing, you probably only typed @k{RET} if
#     the default buffer was @f{*scratch*}, or if it was different, then you
#     typed just part of the name, such as @c{*sc}, pressed your @k{TAB} key to
#     cause it to expand to the full name, and then typed @k{RET}.
 :: @N{6} :: O mejor dicho, para evitar escribir, probablemente solo necesites
    pulsar @k{RET} si @f{*scratch*} es el buffer por defecto, de ser
    diferente, solo escribe parte del nombre, por ejemplo @c{*sc}, luego
    presiona la tecla @k{TAB} para hacer que se expanda el nombre completo, y
    finalmente pulsa @k{RET}.

#  :: @N{7} :: Remember, this expression will move you to your most recent
#     other buffer that you cannot see. If you really want to go to your most
#     recently selected buffer, even if you can still see it, you need to
#     evaluate the following more complex expression:
 :: @N{7} :: Recuerda, esta expresión te desplaza al buffer diferente más
    reciente que no puedas ver. Si realmente quieres ir al ultimo búfer
    seleccionado, incluso si es visible, es necesario evaluar la siguiente
    expresión más compleja:

#     ..src > elisp
#       (switch-to-buffer (other-buffer (current-buffer) t))
#     < src..
    ..src > elisp
      (switch-to-buffer (other-buffer (current-buffer) t))
    < src..

#     In this case, the first argument to @c{other-buffer} tells it which
#     buffer to skip––the current one––and the second argument tells
#     @c{other-buffer} it is OK to switch to a visible buffer. In regular use,
#     @c{switch-to-buffer} takes you to an invisible window since you would
#     most likely use @k{C-x o} @%c(other-window) to go to another visible
#     buffer.
    En este caso, el primer argumento de @c{other-buffer} le dice a que búfer
    saltar––el actual––y el segundo argumento @c{other-buffer} le indica que
    esta BIEN cambiar a un búfer visible. La utilidad de @c{switch-to-buffer} es
    llevarte a una ventana invisible ya que probablemente usarias
    @k{C-x o} @%c(other-window) para ir a otro búfer visible.

#  :: @N{8} :: According to Jared Diamond in @e{Guns, Germs, and Steel}, “…
#     zebras become impossibly dangerous as they grow older” but the claim here
#     is that they do not become fierce like a tiger.  (1997, W. W. Norton and
#     Co., ISBN 0-393-03894-2, page
#     171)
 :: @N{8} :: Segun Jared Diamond en @e{Guns, Germs, and Steel}, “…
    las cebras se vuelven increiblemente peligrosas a medida que envejecen”
    pero la afirmacion aquí es que no se vuelven feroces como un tigre. (1997,
    W. W. Norton and Co., ISBN 0-393-03894-2, pagina 171)

#  :: @N{9} :: Actually, you can @c{cons} an element to an atom to produce a
#     dotted pair. Dotted pairs are not discussed here; see Section @l{elisp.html#Dotted
#     Pair Notation<>Dotted Pair Notation} in @e{The GNU Emacs Lisp Reference
#     Manual}.
 :: @N{9} :: Actualmente, se puede aplicar @c{cons} a un elemento y un átomo
    para producir a par punteado. Los pares punteados no se discuten aquí;
    Consulta la Seccion @l{elisp.html#Dotted
    Pair Notation<>Dotted Pair Notation} en @e(El Manual de Referencia de GNU
    Emacs Lisp).

#  :: @N{10} :: More precisely, and requiring more expert knowledge to
#     understand, the two integers are of type ‘Lisp_Object’, which can also be
#     a C union instead of an integer type.
 :: @N{10} :: Más precisamente, y requiriendo un conocimiento más experto para
    entenderlo, los dos enteros son del tipo ‘Lisp_Object’, que también puede
    ser una unión C en lugar de un tipo entero.

#  :: @N{11} :: You can write recursive functions to be frugal or wasteful of
#     mental or computer resources; as it happens, methods that people find
#     easy––that are frugal of ‘mental resources’––sometimes use considerable
#     computer resources. Emacs was designed to run on machines that we now
#     consider limited and its default settings are conservative. You may want
#     to increase the values of @c{max-specpdl-size} and
#     @c{max-lisp-eval-depth}. In my @f{.emacs} file, I set them to 15 and 30
#     times their default value.
 :: @N{11} :: Puedes escribir funciones recursivas para que sean frugales o
    derrochen recursos mentales o computacionales; como sucede, los métodos que
    la gente encuentra fáciles––que son frugales de ‘recursos mentales’––algunas
    veces usan considerables recursos del computador. Emacs fué diseñado para
    ejecutarse en máquinas que ahora consideramos limitadas y su configuracion
    por defecto es conservadora. Es posible que desees incrementar los valores de
    @c{max-specdl-size} y @c{max-lisp-eval-depth}. En mi fichero @f{.emacs}, yo
    los asigno a 15 o 30 veces su valor predeterminado.

#  :: @N{12} :: The phrase @:{tail recursive} is used to describe such a
#     process, one that uses ‘constant space’.
 :: @N{12} :: La frase @:{recursion de cola} se utiliza para describir tal
    proceso, uno que usa ‘espacio constante’.

#  :: @N{13} :: The jargon is mildly confusing: @c{triangle-recursive-helper}
#     uses a process that is iterative in a procedure that is recursive. The
#     process is called iterative because the computer need only record the
#     three values, @c{sum}, @c{counter}, and @c{number}; the procedure is
#     recursive because the function ‘calls itself’. On the other hand, both
#     the process and the procedure used by @c{triangle-recursively} are called
#     recursive. The word ‘recursive’ has different meanings in the two
#     contexts.
 :: @N{13} :: La jerga es ligeramente confusa: @c{triangulo-recursivo-auxiliar}
    usa un proceso que es iterativo en un procedimiento que es recursivo. El
    proceso se llama iterativo porque el ordenador solo necesita registrar los tres
    valores, @c{suma}, @c{contador}, y @c{número}: el procedimiento es recursivo
    porque la función ‘se llama a sí misma’. Por otra parte, tanto el proceso
    como el procedimiento usado por @c{triangulo-recursivo} se denominan
    recursivos. La palabra ‘recursivo’ tiene significados diferentes en los dos
    contextos.

#  :: @N{14} :: You may also add @f{.el} to @f{~/.emacs} and call it a
#     @f{~/.emacs.el} file. In the past, you were forbidden to type the extra
#     keystrokes that the name @f{~/.emacs.el} requires, but now you may. The
#     new format is consistent with the Emacs Lisp file naming conventions; the
#     old format saves typing.
 :: @N{14} :: Se puede añadir @f{.el} a @f{~/.emacs} y llamarlo
    @f{~/.emacs.el}. En el pasado, se prohibia escribir los atajos de
    teclado extra que el nombre @f{~/.emacs.el} requiere, pero ahora
    se puede hacer. El nuevo formato es consistente con las conveniciones de nombres
    de ficheros Emacs Lisp; el viejo formato mantiene la escritura.

#  :: @N{15} :: When I start instances of Emacs that do not load my @f{.emacs}
#     file or any site file, I also turn off blinking:
 :: @N{15} :: Cuando inicio instancias de Emacs que no cargan mi
    fichero @f{.emacs} o cualquier fichero, también desactivo
    el parpadeo:

#     ..srci > sh
#       > emacs -q --no-site-file -eval '(blink-cursor-mode nil)'
#     < srci..
    ..srci > sh
      > emacs -q --no-site-file -eval '(blink-cursor-mode nil)'
    < srci..

#     Or nowadays, using an even more sophisticated set of options,
    O tambien usando un conjunto más sofisticado de opciones,

#     ..srci > sh
#       > emacs -Q -D
#     < srci..
    ..srci > sh
      > emacs -Q -D
    < srci..

#  :: @N{16} :: I also run more modern window managers, such as Enlightenment,
#     Gnome, or KDE; in those cases, I often specify an image rather than a
#     plain color.
 :: @N{16} :: También ejecuto gestores de ventanas más modernos,
    como Enlightenment, Gnome, o KDE; en esos casos, a menudo
    especifico una imagen en lugar de un color plano.
